本文共 3455 字,大约阅读时间需要 11 分钟。
CyclicBarrier 类是一个同步辅助类,实现了一个称为障栅的集合点,在不是所有线程都到达集合点前,线程之前可以相互等待.Cyclic 的含义是“循环的,周期的”,代表该障栅在所有等待的线程到达集合点并被释放后可以循环使用.
CyclicBarrier 类比较适合于线程数量固定的情况.CyclicBarrier(int parties) //创建障栅对象;parties为需要等待的线程个数.CyclicBarrier(int parties,Runnable barrierAction) // barrierAction 定义最后一个进入障栅的线程要执行的动作.
在障栅的对象上可以调用 await()
方法,该方法需要放置到 try…catch…语句块中,并捕获 InterruptedException 和 BrokenBarrierException 异常.线程在完成自己的工作后调用 await() 方法等待.当最后一个线程调用 await() 方法后,将唤醒所有等待线程,并继续该障栅后的工作.
倒计时门闩就像一个带有计数器开关的门,只有在门前等待的线程到达一定数量时,门闩才会打开,线程才可以继续执行.
倒计时门闩由 CountDownLatch 类实现,该类从 Object 继承而来,可以通过一个给定的值进行初始化,通常在同步状态中保存的是当前的计数值,线程调用 await() 方法等待;方法countDown()
会导致计数值递减,当计数值为零时,所有的倒计时门闩范围内的等待线程的阻塞状态将解除. CountDownLatch(int count)
await()
方法的线程会被挂起,它会等待直到count值为0才继续执行await()
类似,只不过等待一定的时间后count值还没变为0的话就会继续执行信号量机制通常用于限制对于某个资源同时访问的线程数量.
信号量机制是一种典型的同步机制,可以用于解决常用的线程同步问题. 在 Java 并发库中,类 Semaphore 可以实现信号量机制,其定义如下:public class Semaphore extends Object implements Serializable
信号量管理了一个许可集合,可以通过方法 acquire() 获取一个许可,如果没有许可则可以等待.通过方法 release()
可以释放一个许可. Semaphore(int permits)
// 用给定的许可数创建一个 Semaphore 对象.
Semaphore(int permits,boolean fair)
// 设置许可分配策略:公平分配/非公平分配 acquire()
获取一个许可,如果没有许可可以获取,则阻塞.使用场景:
银行设置了4个窗口可以同时办理业务,现在有20个顾客需要办理业务,使用信号量机制可以实现这种场景.同步队列是一个没有数据缓冲的阻塞队列,在同步队列上插入操作必须等待相应的删除执行完成后才能执行,反之亦然.
不能调用peek()
方法查看队列中是否有数据,也不允许对整个队列遍历. 类 SynchronousQueue 是 Java 集合框架中的一员.该类的定义形式如下: public class SynchronousQueue extends AbstraceQueue implements BlockingQueue,Serializable 其中 E 指明同步队列中元素的类型.
public SynchronousQueue()
public SynchronousQueue(boolean fair) //使用公平性策略创建同步队列drainTo()
一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数), 通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁.offer(E e)
如果另一个线程正在等待以便接收指定元素,则将指定元素插入到此队列.offer(E o, long timeout, TimeUnit unit)
将指定元素插入到此队列,如有必要则等待指定时间,以便另一个线程接受它.poll()
如果另一个线程当前正要使用某个元素,则获取并移除此队列的头poll(long timeout, TimeUnit unit)
获取并移除此队列的头,如有必要则等待指定的时间,以便另一个线程插入它.put(E o)
将指定元素 o 添加到此队列,如有必要则等待另一个线程接收它.take()
获取并移除此队列的头,如有必要则等待另一个线程插入它.使用场景:使用同步队列实现生产者和消费者的问题.
由于使用同步队列作为公共缓冲区,故生产者和消费者对公共缓冲区的操作不再需要添加额外的同步控制操作. 生产者对缓冲区进行插入操作,消费者对缓冲区进行删除操作.两者协同操作,不允许一个人连续执行两次.从 JDK1.5 版本开始提供了线程间数据交换的功能,该功能可以通过 Exchanger 类完成.
public class Exchanger(V) extends Object
参数 V 表示要交换数据的类型.该类从 Object 类继承,它提供了一个同步点,在该同步点上线程间可以交换数据.一个线程通过 exchange()
方法将其数据提供给另一个线程,并接受另一个线程的数据.
V exchange( V x)
该方法将等待另一个线程到达交换点,然后交换指定的数据 x,该方法将返回的交换后的数据.在日常生活中,我们在做一件事情的时候,习惯把一件事情划分为若干个阶段,然后规定每个阶段的任务和完成的时间,从而实现阶段化的控制和管理,阶段化处理往往在完成某一项工作时很高效.
从 JDK1.7 版本开始引入类 Phaser,它是 Java 并发库中功能强大并且较复杂的一个功能,可以用来完成阶段式的并发执行任务的功能. Phaser 类直接从 Object 类继承,它是一个可复用的同步障栅,与 CyclicBarrier 和 CountDownLatch 功能类似,但使用上更加灵活.转载地址:http://pyazi.baihongyu.com/