CountDownLatch 的使用
1.介紹
此類所提供的功能是判斷count計數不爲0時則呈wait狀態,在屏障處等待它也是一個同步功能的輔助類:
給定一個計數,當使用這個CountDownLatch的類的線程判斷計數不爲0時,則呈wait狀態,如果爲0則繼續
運行。
2.實現
實現等待與繼續運行的效果分別需要使用awiat()和countDown()方法來進行。調用await()方法時判斷
計數是否爲0,如果不爲0則呈等待狀態,其他線程可以countDown()方法將計數減1,計數爲0時,等待的線
程就繼續運行。getCount() 就是獲得當前的計數個數。此計數無法被重置。
3.一個具體的跑步比賽
代碼
/**
* CountDownLatch 是一個同步功能的輔助類,使用效果是給定一個計數
* 當使用這個 CountDownLatch 的線程判斷技術不爲0 時則當前線程呈wait狀態
* 爲0則繼續運行
*/
package com.lhc.concurrent.countDownLatch;
import java.util.concurrent.CountDownLatch;
public class MyThread extends Thread {
private CountDownLatch comingTag;
private CountDownLatch waitTag;
private CountDownLatch waitRunTag;
private CountDownLatch beingTag;
private CountDownLatch endTag;
public MyThread(CountDownLatch comingTag, CountDownLatch waitTag, CountDownLatch waitRunTag, CountDownLatch beingTag, CountDownLatch endTag) {
super();
this.comingTag = comingTag;
this.waitTag = waitTag;
this.waitRunTag = waitRunTag;
this.beingTag = beingTag;
this.endTag = endTag;
}
@Override
public void run() {
System.out.println("各位運動員正在到達起跑點的路上");
try {
/**
* 各個線程運行使comingTag -1,
* 然後waitTag 等待
* 然後waitRunTag - 1
* 然後beingTag 等待
* 然後endTag - 1
*/
Thread.sleep((int) Math.random() * 10000);
System.out.println(Thread.currentThread().getName() + "到起跑點了");
comingTag.countDown();
System.out.println("等待裁判說準備");
waitTag.await();
System.out.println("準備起跑");
Thread.sleep((int) (Math.random() * 10000 + 1000));
waitRunTag.countDown();
beingTag.await();
System.out.println(Thread.currentThread().getName() + " 運動員開跑");
Thread.sleep((int) (Math.random() * 10000 + 1000));
endTag.countDown();
System.out.println(Thread.currentThread().getName() + "運動員到達終點");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CountDownLatch comingTag = new CountDownLatch(10);
CountDownLatch waitTag = new CountDownLatch(1);
CountDownLatch waitRunTag = new CountDownLatch(10);
CountDownLatch beingTag = new CountDownLatch(1);
CountDownLatch endTag = new CountDownLatch(10);
MyThread[] myThreads = new MyThread[10];
for (int i = 0; i < myThreads.length; i++) {
myThreads[i] = new MyThread(comingTag, waitTag, waitRunTag, beingTag, endTag);
myThreads[i].start();
}
System.out.println("裁判員在等待選手的到來");
try {
/**
* 與上面的run()方法結合起來看
* comingTag 等待
* waitTag -1
* waitRunTag 等待
* beingTag -1
* endTag 等待
*/
comingTag.await();
System.out.println("所有運動員到來,裁判巡視五秒");
Thread.sleep(5000);
waitTag.countDown();
System.out.println("各就各位");
waitRunTag.await();
Thread.sleep(2000);
System.out.println("開始跑");
beingTag.countDown();
endTag.await();
System.out.println("Game Over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
打印結果
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
各位運動員正在到達起跑點的路上
Thread-2到起跑點了
Thread-5到起跑點了
等待裁判說準備
各位運動員正在到達起跑點的路上
Thread-6到起跑點了
等待裁判說準備
各位運動員正在到達起跑點的路上
裁判員在等待選手的到來
各位運動員正在到達起跑點的路上
Thread-4到起跑點了
等待裁判說準備
Thread-3到起跑點了
等待裁判說準備
等待裁判說準備
Thread-8到起跑點了
等待裁判說準備
Thread-9到起跑點了
等待裁判說準備
Thread-7到起跑點了
等待裁判說準備
Thread-1到起跑點了
等待裁判說準備
Thread-0到起跑點了
等待裁判說準備
所有運動員到來,裁判巡視五秒
各就各位
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
準備起跑
開始跑
Thread-5 運動員開跑
Thread-1 運動員開跑
Thread-4 運動員開跑
Thread-7 運動員開跑
Thread-3 運動員開跑
Thread-8 運動員開跑
Thread-9 運動員開跑
Thread-6 運動員開跑
Thread-2 運動員開跑
Thread-0 運動員開跑
Thread-1運動員到達終點
Thread-6運動員到達終點
Thread-5運動員到達終點
Thread-7運動員到達終點
Thread-3運動員到達終點
Thread-8運動員到達終點
Thread-0運動員到達終點
Thread-4運動員到達終點
Thread-9運動員到達終點
Thread-2運動員到達終點
Game Over