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