6.5 JUC — 同步器

同步器名称 作用
CountDownLatch 倒数计数器,构造时设定计数值,当计数值归零后,所有阻塞线程恢复执行;其内部实现了AQS框架
CyclicBarrier 循环栅栏,构造时设定等待线程数,当所有线程都到达栅栏后,栅栏放行,然后再进行新的一次循环。其内部通过ReentrantLock和Condition实现同步
Semaphore 信号量,类似于“令牌”,用于控制共享资源的访问数量;其内部实现了AQS框架
Exchanger 交换器,类似于双向栅栏,用于线程之间的配对和数据交换;其内部根据并发情况有“单槽交换”和“多槽交换”之分
Phaser 多阶段栅栏,相当于CyclicBarrier的升级版,可用于分阶段任务的并发控制执行;其内部比较复杂,支持树形结构,以减少并发带来的竞争

CountDownLatch

CountDownLatch是一个辅助同步器类,用来作计数使用,先设定一个计数初始值,当计数降到0时,将会触发一些事件。类似于生活中饭局,先来的人要等人齐了才能开饭。
初始计数值在构造CountDownLatch对象时传入,每调用一次 countDown() 方法,计数值就会减1。线程可以调用CountDownLatch的await方法进入阻塞,当计数值降到0时,所有之前调用await阻塞的线程都会释放。
注意:CountDownLatch的初始计数值一旦降到0,无法重置。如果需要重置,可以考虑使用CyclicBarrier。
一般有以下两种用法:

  1. 作为开关/入口:将初始计数值为1的 CountDownLatch 作为一个的开关或入口,在调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。
  2. 作为完成信号:将初始计数值为N的 CountDownLatch作为一个完成信号点:使某个线程在其它N个线程完成某项操作之前一直等待。

CyclicBarrier

CyclicBarrier类似是一个可以循环使用的CountDownLatch,让线程到达栅栏时被阻塞(调用await方法),直到到达栅栏的线程数满足指定数量要求时,栅栏才会打开放行。

构造器:
CyclicBarrier(int parties); 参数parties就是传入的计数总数。
CyclicBarrier(int parties, Runnable barrierAction);  该构造器制定了一个计数总数和一个用于达到计数总数后立刻执行的Runnable任务。

Semaphore

Semaphore,又名信号量,这个类的作用有点类似于“许可证”。有时因为一些原因需要控制同时访问共享资源的最大线程数量,比如出于系统性能的考虑需要限流,或者共享资源是稀缺资源,以保证合理的使用公共资源。
Semaphore维护了一个许可集,其实就是一定数量的“许可证”。当有线程想要访问共享资源时,需要先获取(acquire)的许可;如果许可不够了,线程需要一直等待,直到许可可用。当线程使用完共享资源后,可以归还(release)许可,以供其它需要的线程使用。
构造器:
Semaphore(int permits); 参数permits是许可证数量。
Semaphore(int permits, boolean fair); 参数fair控制公平/非公平锁

Exchanger

交换器,这个类的主要作用是交换数据。Exchanger可以看成是一个双向栅栏。

生产者/消费者 先来到交换器处,如果对方还未到,就会进行等待直到对方来到,通过调用exchange函数来达到交换信息的目的。
public V exchange(V x);通过泛型V来交换各自定制型的信息。

Phaser

功能与 CyclicBarrier和CountDownLatch有些类似,类似于一个多阶段的栅栏,并且功能更强大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章