1. CountDownLatch
一个同步工具,允许一个或多个线程去等待其他线程中执行的一系列操作完成。
什么意思呢?就是说,允许这个线程阻塞,直到,其他线程的所有操作都完成之后,在继续执行。举个例子。
public static void main(String[] args) throws InterruptedException {
final CountDownLatch downLatch = new CountDownLatch(5);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.err.println(i);
try {
Thread.sleep(1000);
downLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
downLatch.await();
System.err.println("结束了");
}
上面的例子 等五个线程都执行完毕之后,主线程才会继续执行。
用法如下:
- CountDownLatch(5) 后面的数字代表等待几个线程完成
- 每当一个线程完成的时候,downLatch.countDown(),来使计数-1
- downLatch.await() ,直到计数为0的时候,才会执行他下面的逻辑。
2. CyclocBarrier
也是一个同步工具,允许一系列线程等待其中每一个都到达一个公共的障碍点,然后在继续执行。并且,等待的线程都释放之后,可以重用
作为山沟沟里的娃,受够了坐车等人的折磨。举个例子。
public static void main(String[] args){
final CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.err.println("到齐了。可以开车了");
}
});
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
System.err.println("买票了"+ finalI);
try {
cyclicBarrier.await();
System.err.println("起飞了"+ finalI);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
输出结果:
用法:
- CyclicBarrier(int parties, Runnable barrierAction) 构造函数中,参数一个是调用await的线程数,一个是到达障碍点之后的处理。
- cyclicBarrier.await() 表示我要等其他也到达,才要继续执行
3. Phaser
一个可重用的同步工具,可以实现提CyclicBarrier和CountDownLatch的功能,但是还有其他高级的功能。
3.1 实现CountDownLatch的功能
- CountDownLatch#countDown 由Phaser#arrive 代替
- CountDownLatch#await 由Phaser#awaitAdvance 代替
举个例子:
final Phaser phaser = new Phaser(5);
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
System.err.println(finalI);
phaser.arrive();
}
}).start();
}
phaser.awaitAdvance(phaser.getPhase());
System.err.println("结束了");
3.2 实现CyclocBarrier的功能
虽然说能实现,但是还是比较弱。
- CyclicBarrier#await 由Phaser#arriveAndAwaitAdvance代替。
final Phaser phaser = new Phaser(5);
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
System.err.println("买票了"+ finalI);
phaser.arriveAndAwaitAdvance();
System.err.println("起飞了"+ finalI);
}
}).start();
}
3.3 高级功能
- 支持register和bulkRegister方法来调整任务数,arriveAndDeregister方法支持在任务到达的时候减少任务数
- arriveAndAwaitAdvance 表示任务到达并且等待其他任务到达
- 支持终止,如果onAdvance返回true,就会终止,如果注册任务数为0,也会终止。forceTermination方法会强制终止。
- 从它的构造函数来看,Phaser支持分层,Phaser(Phaser parent, int parties)。可以通过这些来构造出一个层次的Phaser
这些功能就不举例子了。有兴趣的同学可以去看下文档。
参考资料
- JDK Phaser
- What’s New on Java 7 Phaser