CountDownLatch
CountDownLatch可以用來保證,一個或者多個線程阻塞在某處,待某些其他指令執行完畢後再開始執行。初始化時指定一個count,程序會在await()方法的掉用處阻塞,每次調用countDown()會使得count減一,當count等於0,await後面的線程將得以執行。值得一提的是,count的值不能重置。
注意,count的值被置爲N,只要通過countDown()的調用將其變爲0,無論是N個線程執行完,還是同一個操作執行了N次,await()方法就不會阻塞。
下面給出一個CountDownLatch的例子。
package syncronizationTool;
import java.util.concurrent.CountDownLatch;
public class TestCountDownLatch {
public static void main(String [] args) throws Exception {
int actorNum = 5;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(actorNum);
for(int i = 0; i < actorNum; i++){
new Thread(new Actor("Actor"+i, startSignal, doneSignal)).start();
}
System.out.println("各部門注意,演員請就位,Action~~~");//導演喊Action,各演員開始演戲
startSignal.countDown();
System.out.println("拍戲進行中");
doneSignal.await();
System.out.println("咔~~~");//導演喊咔,本場演完
}
}
class Actor implements Runnable {
private String name;
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Actor(String name, CountDownLatch startSignal, CountDownLatch doneSignal){
this.name = name;
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
@Override
public void run() {
try{
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ie) {
}
}
void doWork(){
System.out.println(name + " is performing...");
}
}
CyclicBarraiar
cyclicBarriar用於使一組線程互相等待,直到barriar被打破。固定值N是可以reset的。
例子:
public class TestCyclicBarriar {
public static void main(String [] args){
CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("滿人"));
for(int i = 0; i < 100; i++){
new Thread(()-> {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}