并发编程八之juc同步器的使用和场景介绍以及理解它们之间的区别

关于并发编程的专题已经过了一段时间没更新,最近给中心培训并发框架

题目,再次更新专题。

JDK中JUC同步器提供以下类,它们每个的实现方式都不一样。

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • Exchanger


线程计数器CountDownLatch


在前面我们已经分析过它的源码实现《并发编程ContDownLatch源码分析》。在我们项目中大量使用CountDownLatch,而线上也出现过使用不当造成生产问题。在这里就不在分析源码, 我们讲一些注意事项。

此类有以下主要方法

  • countDown
  • await

面试题

  1. 请问如何使用jdk1.5版本 之前实现CountDownLatch?
  2. 如何使用jdk1.5版本实现CountDownLatch?
  3. 为什么countDown会计数?


栅栏锁 CyclicBarrier


CyclicBarrier人称栅栏锁,是让一组线程到达一个屏障时被阻塞,当屏障的线程数达到指定数量后屏障会自动开门,所有被屏障拦截的线程会继续运行。

场景示例

我们经常做的流水大巴车就是一个很典型的例子。当车子未满时,一直在等乘客,若小于车位数量时车子一直不开车。 在客流量比较大时,几分钟就能满车,大巴车很快就可以走。

主要方法:

  • await
  • isBroken //判断是否被阻塞
  • getNumberWaiting //阻塞线程数
  • getParties //并发执行数


构造方法必须指定一个屏障数:


CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

构造方法还可以指定一个线程,在每次屏障结果后执行此线程


CyclicBarrier cyclicBarrier = new CyclicBarrier(3,()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程"+Thread.currentThread());
});

网上有一些文章讲reset是CyclieBarrier的优点,在我使用中发现这个是个多余。

使用注意事项:若线程数不是指定屏障的倍数时会一直阻塞。

面试题

  1. CyclicBarrier的实现原理是什么?
  2. 与CountDownLatch的不同点有哪些?


信号号Semaphore


Semaphore信号量控制活动数,内部使用AQS来实现,它有两个策略默认非公平策略。

主要方法:

  • acquire
  • release


构造方法指定信号数,通过构造方法指定策略


Semaphore semaphore = new Semaphore(2);
Semaphore semaphore = new Semaphore(2,true);


Semaphore通过 acquire 进行获取许可证,当许可证用完时,必须使用release 方法释放许可证,否则无法获取许可证。

使用场景:互联网秒杀、停车场

回顾面试题:

  1. Semaphore 的实现原理是什么?
  2. 与CyclicBarrier的不同点有哪些?


交换器Exchanger


Exchanger两个线程之间数据切换,若一个线程执行exchange方法,则一直等待另一个线程也执行。若没有另一个线程执行exchange 方法,则当前线程处于阻塞。

主要方法

  • exchange


使用场景:遗传算法、数据校正

注意事项:exchange方法是成对出现,若不成对,则会一直阻塞

以上是根据个人理解做了分析,如有不正确请留言讨论。

----------



分享到:


相關文章: