CountDownLatch

是什么

CountDownLatch的字面意思:倒计时 门栓

它的功能是:让一些线程阻塞直到另一些线程完成一系列操作后才唤醒。

它通过调用await方法让线程进入阻塞状态等待倒计时0时唤醒。

它通过线程调用countDown方法让倒计时中的计数器减去1,当计数器为0时,会唤醒哪些因为调用了await而阻塞的线程。

  • 底层是使用AQS实现的

案例

假设老板开一个紧急会议,他先到会议室等着所有人签到然后开始开会,可以使用CountDownLatch进行模拟。

 public static void main(String[] args) {
CountDownLatch countDownLatch=new CountDownLatch(5); for (int i=1;i<=5;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"签到!");
countDownLatch.countDown();
},"第"+i+"個人").start();
} try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("老板宣布人夠了开始开会!");
}

运行结果:

//注意这里的签到顺序可以随意
第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!

CyclicBarrier

是什么

CyclicBarrier [ˈsaɪklɪk] [ˈbæriər] 的字面意思:可循环使用的屏障 【栅栏】

它的功能是:让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障,所有被屏障拦截的线程才会继续执行。

它通过调用await方法让线程进入屏障,

  • 底层是通过ReentrantLock以及Condition中的await和signal实现
 /** The lock for guarding barrier entry */
private final ReentrantLock lock = new ReentrantLock();
/** Condition to wait on until tripped */
private final Condition trip = lock.newCondition();

图例

例子

还是上面的开会的例子,我们使用CyclicBarrier实现。

public static void main(String[] args) {
CyclicBarrier cyclicBarrier=new CyclicBarrier(5,()->{
System.out.println("老板宣布人夠了开始开会!!");
}); for (int i=1;i<=5;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"签到!");
cyclicBarrier.await(); //如果等待的线程数未到,这里将一直等待
//等线程数够了下面语句将继续执行......
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"第"+i+"個人").start();
}
}

运行结果:

第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!!

Semaphor

是什么

Semaphor [ˈseməfɔːr] 信号量的意思;

它主要用于两个目的:

  • 用于多个共享资源互斥使用。【也就是具有锁的功能】

    一个停车场有多个停车位,这多个停车位对应汽车来说就是多个共享资源,Semaphor可以实现多个停车位和多个汽车之间的互斥。
  • 用于控制并发线程数。(就是控制同时得到共享资源的线程数量)

    在创建Semaphor时可以指定并发线程数,
    //permits :允许
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//还可以指定是否为公平锁
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
  • 信号量为1时 相当于独占锁 信号量大于1时相当于共享锁。

例子

我们测试使用Semaphor实现控制线程并发访问方法。

/**
* 测试使用Semaphor信号量控制方法的访问
*/
public class TestSemaphor {
Semaphore semaphore=new Semaphore(5);
/**
* 假设并发只能为5个
*/
public void pay(){
try {
//在 semaphore.acquire() 和 semaphore.release()之间的代码,同一时刻只允许指定个数的线程进入!
semaphore.acquire();
System.out.println("这是支付的方法!");
Thread.sleep(2000);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
TestSemaphor ts=new TestSemaphor();
for (int i=0;i<10;i++){
new Thread(()->{
ts.pay();
},"线程"+i).start();
}
}

运行效果:

线程0这是支付的方法!
线程3这是支付的方法!
线程6这是支付的方法!
线程5这是支付的方法!
线程1这是支付的方法! //注意这里是执行的暂停点 线程7这是支付的方法!
线程8这是支付的方法!
线程2这是支付的方法!
线程4这是支付的方法!
线程9这是支付的方法!

注意结果:10个线程分了两批执行的,也就是说我们控制了访问pay方法的线程数量,每次并发只能是5个!

CountDownlatch和CyclicBarrier以及Semaphor的区别是

  • CountDownLatch是做减法,CyclicBarrier是做加法,Semaphor的临界资源可以反复使用

  • CountDownLatch不能重置计数,CycliBarrier提供的reset()方法可以重置计数,不过只能等到第一个计数结束。Semaphor可以重复使用。

  • CountDownLatch和CycliBarrier不能控制并发线程的数量,Semaphor可以实现控制并发线程的数量。

资源

更好的介绍

最新文章

  1. XE3随笔15:从XML中解析
  2. KVM 介绍(1):简介及安装
  3. 如何防止鼠标移出移入子元素触发mouseout和mouseover事件
  4. pandas 修改 DataFrame 列名
  5. HttpHandler和ashx要实现IRequiresSessionState接口才能访问Session信息(转载)
  6. 007 The Inheritance In JAVA
  7. 记录一个NPE问题
  8. 一些关于StringAPI的题目
  9. Go 字符串连接+=与strings.Join性能对比
  10. Vue.js 3.0 新特性预览
  11. python 经典博客链接
  12. Scala进阶之路-Scala中的泛型介绍
  13. 构建Java并发模型框架
  14. ruby里面module和class的区别
  15. Learning notes | Data Analysis: 1.1 data evaluation
  16. Linux进程守护——Supervisor 使用记录
  17. Gulp插件autoprefixer的使用
  18. Spring security UserDetailsService autowired注入失败错误
  19. 常见企业IT支撑【3、SVN代码版本控制系统】
  20. HTML表格-table

热门文章

  1. hdu 1502 大数dp
  2. winfrom_权限设置_TreeView的相关问题
  3. Qt调用VS生成的dll
  4. 用python 打印出爱心
  5. property配置
  6. world 页面横向
  7. sql临时表 通过临时表循环处理数据
  8. TF版网络模型搭建常用代码备忘
  9. STM32L1xx——ADC(中断/DMA)样例代码
  10. web开发:javascript高级