在Java中,Thread.join()
方法用于等待一個(gè)線程執(zhí)行完畢后再繼續(xù)執(zhí)行當(dāng)前線程。以下是一些常見(jiàn)的線程協(xié)作技巧,這些技巧可以幫助你更好地控制線程的執(zhí)行順序和共享資源:
join()
方法來(lái)確保線程按照特定的順序執(zhí)行。例如,如果你有一個(gè)主線程和一個(gè)子線程,你可能希望主線程在子線程之前執(zhí)行完畢。你可以通過(guò)在主線程中調(diào)用子線程的join()
方法來(lái)實(shí)現(xiàn)這一點(diǎn)。Thread t1 = new Thread(new Runnable() {
public void run() {
// 子線程的任務(wù)
}
});
t1.start();
t1.join(); // 主線程會(huì)等待t1執(zhí)行完畢后再繼續(xù)執(zhí)行
// 接下來(lái)主線程的任務(wù)
wait()
方法用于使當(dāng)前線程等待,直到另一個(gè)線程調(diào)用同一對(duì)象的notify()
或notifyAll()
方法。這可以用于線程間的協(xié)作,例如生產(chǎn)者-消費(fèi)者問(wèn)題。class Buffer {
private boolean empty = true;
public synchronized void put(Object item) throws InterruptedException {
while (!empty) {
wait(); // 如果緩沖區(qū)已滿,則等待
}
empty = false;
notify(); // 通知等待的線程緩沖區(qū)非空
}
public synchronized Object take() throws InterruptedException {
while (empty) {
wait(); // 如果緩沖區(qū)為空,則等待
}
empty = true;
notify(); // 通知等待的線程緩沖區(qū)非滿
return item;
}
}
CountDownLatch
是一個(gè)同步輔助類(lèi),它允許一個(gè)或多個(gè)線程等待直到一組操作完成。這在需要等待多個(gè)線程完成后再執(zhí)行下一步操作的場(chǎng)景中非常有用。CountDownLatch latch = new CountDownLatch(3); // 等待3個(gè)線程完成
Thread t1 = new Thread(new Runnable() {
public void run() {
// 任務(wù)1
latch.countDown(); // 完成任務(wù)1
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
// 任務(wù)2
latch.countDown(); // 完成任務(wù)2
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
// 任務(wù)3
latch.countDown(); // 完成任務(wù)3
}
});
t1.start();
t2.start();
t3.start();
try {
latch.await(); // 主線程會(huì)等待所有任務(wù)完成后再繼續(xù)執(zhí)行
} catch (InterruptedException e) {
e.printStackTrace();
}
CyclicBarrier
是一個(gè)可重復(fù)使用的同步輔助類(lèi),它允許一組線程互相等待,直到所有線程都到達(dá)某個(gè)屏障(barrier)點(diǎn)。這在需要多個(gè)線程協(xié)同完成任務(wù)(如數(shù)據(jù)分片處理)的場(chǎng)景中非常有用。CyclicBarrier barrier = new CyclicBarrier(3); // 3個(gè)線程需要協(xié)同完成任務(wù)
Thread t1 = new Thread(new Runnable() {
public void run() {
// 任務(wù)1
try {
barrier.await(); // 等待其他線程完成任務(wù)
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
// 任務(wù)2(依賴于任務(wù)1和其他線程的結(jié)果)
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
// 任務(wù)2
try {
barrier.await(); // 等待其他線程完成任務(wù)
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
// 任務(wù)3(依賴于任務(wù)1和其他線程的結(jié)果)
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
// 任務(wù)3
try {
barrier.await(); // 等待其他線程完成任務(wù)
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
// 任務(wù)4(依賴于任務(wù)1、2和其他線程的結(jié)果)
}
});
t1.start();
t2.start();
t3.start();
這些技巧可以幫助你更好地控制線程的執(zhí)行順序和共享資源,從而實(shí)現(xiàn)更高效的并發(fā)編程。