我寫了一個小程式來演示 CountDownLatch 類在 java 中的用法。但是,它沒有按預期作業。我創建了 5 個執行緒并為每個執行緒分配了任務。現在,每個執行緒都將等待啟動信號。一旦啟動信號打開,所有執行緒都會開始作業并呼叫 countDown()。現在,我的主執行緒等待所有執行緒完成其作業,直到它收到完成信號。但輸出不是預期的。如果我在概念中遺漏任何內容,請提供幫助。下面是程式。
class Task implements Runnable{
private CountDownLatch startSignal;
private CountDownLatch doneSignal;
private int id;
Task(int id, CountDownLatch startSignal, CountDownLatch doneSignal){
this.startSignal = startSignal;
this.doneSignal = doneSignal;
this.id = id;
}
@Override
public void run() {
try {
startSignal.await();
performTask();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void performTask() {
try {
System.out.println("Task started by thread : " id);
Thread.sleep(5000);
doneSignal.countDown();
System.out.println("Task ended by thread : " id);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CountDownLatchExample {
public static void main(String[] args) {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(5);
for(int i=0; i < 5; i) {
new Thread(new Task(i, startSignal, doneSignal)).start();
}
System.out.println("Press enter to start work");
new Scanner(System.in).nextLine();
startSignal.countDown();
try {
doneSignal.await();
System.out.println("All Tasks Completed");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
輸出
Press enter to start work
Task started by thread : 0
Task started by thread : 4
Task started by thread : 3
Task started by thread : 2
Task started by thread : 1
Task ended by thread : 4
Task ended by thread : 2
Task ended by thread : 1
All Tasks Completed
Task ended by thread : 0
Task ended by thread : 3
預期產出
Press enter to start work
Task started by thread : 0
Task started by thread : 4
Task started by thread : 3
Task started by thread : 2
Task started by thread : 1
Task ended by thread : 4
Task ended by thread : 2
Task ended by thread : 1
Task ended by thread : 0
Task ended by thread : 3
All Tasks Completed
uj5u.com熱心網友回復:
在你的Task課堂上,你有:
doneSignal.countDown(); System.out.println("Task ended by thread : " id);
換句話說,您在列印“任務結束”之前對鎖存器進行倒計時。這允許主執行緒在所有“任務結束”列印陳述句完成之前從其呼叫中喚醒doneSignal.await()并列印“所有任務已完成”。盡管請注意“錯誤輸出”并不總是會發生;有時您會得到預期的輸出。
只需切換這兩行代碼即可保證您想要的輸出:
System.out.println("Task ended by thread : " id);
doneSignal.countDown();
這確保了 print 陳述句發生在呼叫之前doneSignal.countDown(),它本身發生在主執行緒從doneSignal.await(). 因此,現在上面的“任務結束”列印陳述句發生在主執行緒喚醒并列印“所有任務已完成”訊息之前。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/486655.html
