《Java核心技术卷》读书笔记-并发(十二)- 同步器

39 阅读2分钟

同步器有哪些?

它能做什么说明
CyclicBarrier允许线程集等待直至其中预定数目的线程到达一个公共障栅,然后可以选择执行一个处理障栅的动作当大量的线程需要在它们的结果可用之前完成时
Phaser类似与循环障栅,不过有一个可变的计数JAVA SE7引入
CountDownLatch允许线程集等待知道计数器减为0当一个或多个线程需要等待直到指定数目的事件发生
Exchanger允许两个线程在要交换的对象准备好时交换对象当两个线程工作在同一数据结果的两个实例上的适合,一个向实例添加数据而另一个从实例清除数据
Semaphore允许线程集等待直到被允许继续运行为止限制访问资源的线程总数。
SynchronousQueue允许一个线程把对象交给另一个线程在没有显式同步的情况下,当两个线程准备好将一个对象从一个线程传递到另一个时

信号量

为了通过信号量,线程通过调用acquire请求许可。其实没有实际的许可对象,信号量仅维护一个计数。许可的数目是固定的,由此限制了通过的线程数量。其他线程可以通过调用release释放许可。

倒计时门栓

一个CountDownLatch让一个线程集等待直到计数变为0。倒计时门栓是一次性的,一旦计数为0,就不能用了。

障栅

CyclicBarrier实现了一个集结点(rendezvous)成为障栅(barrier),当一个线程完成了它那部分任务后,我们让它运行到barrier,一旦所有线程都到达了这个barrier,barrier就撤销了。


CyclicBarrier barrier = new CyclicBarrier(nthreads);

  


public void run() {

doWork();

barrier.await();

}

因为是循环的,所以是可以在所有等待线程被释放后被重用的。

Phaser

与CyclicBarrier类似,但更灵活,可以改变不同阶段中参与线程的个数。

交换器Exchanger

可以交换两个线程的数据,相当于共享。典型情况是,一个线程向缓冲区填入数据,另一个线程消耗这些数据。当它们都完成后,相互交换缓冲区。

同步队列

当一个线程调用SynchronousQueue的put方法时,它会阻塞直到另一个线程调用take方法为止,反之亦然。虽然它实现了BlockingQueue接口,但概念上讲,它并不是一个队列,因为它并没有包含任何元素,它的size总是为0。