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();
}
}
}