Java并发包学习(CountDownLatch,Seamphore,CyclicBarrier,Exchanger)
我们常说的“并发包”指的是java.util.concurrent这个包,后面简称 J.U.C,里面包含大量多线程和并发编程的工具。J.U.C 包是 JDK 1.5 版本引入,本文所有内容基于 JDK11。
工具类
工具包内主要有这几个工具:计数器CountDownLatch、回环栅栏(光看名字估计一头雾水)CyclicBarrier、信号量Semaphore、创建线程池的Executors,最后一个交换数据的Exchanger。本章几个工具的原理都是基于 AQS,关于 AQS 和ReentrantLock,都有单独的文章解读,就不专门介绍了。
CountDownLatch
一个计数器,常见这样一种场景:多个任务分发个不同的线程去执行,全部执行完毕后回到主线程。当然有不同的实现方式,用CountDownLatch实现起来就很简单:
int taskNum = 20;CountDownLatch countLatch = new CountDownLatch(taskNum);for (int i = 0; i < taskNum; i++) {new Thread(() -> {try {Thread.sleep(200); //假装做了点什么System.out.println(Thread.currentThread().getName() + "执行完毕");} catch (InterruptedException e) {e.printStackTrace();}countLatch.countDown(); // 减1操作}).start();}try {countLatch.await(); // 阻塞线程,直至countDown方法调用次数等于taskNum,才会释放线程。for循环次数必须大于等于taskNumSystem.out.println("全部任务执行完毕");} catch (InterruptedException e) {e.printStackTrace();}
Seamphore
信号量,类似于控制并发的时候用到的“令牌桶”算法,通过控制信号总数,不断释放和回收信号来控制并发数量。假设有这么一个场景,假设我们有五个通道可以执行任务,任务总数是 40,所以同一时刻只能有最多五个线程执行,其余的要等待,因此我们使用Seamphore来不断方法许可和收回许可:
Semaphore semaphore = new Semaphore(5);for (int i = 0; i < 40; i++) {new Thread(() -> {try {semaphore.acquire(); // 获取许可,获取失败则进入阻塞System.out.println(Thread.currentThread().getName() + "取得许可,开始执行任务");Thread.sleep(new Random().nextInt(2000));System.out.println(Thread.currentThread().getName() + "任务完成,释放许可");semaphore.release(); // 释放许可。释放后激活阻塞线程去争取许可} catch (InterruptedException e) {e.printStackTrace();}}).start();}
CyclicBarrier
回环栅栏光看名字不好理解,其实作用很上面的计数器类似,有点类似于 Java 虚拟机中的“安全点”。执行一个任务的时候,所有线程到达栅栏之后停止,等待所有其他线程都到达这个点,然后一起进入下一阶段。与计数器不同的是,CyclicBarrier可以重复使用,举个栗子:
用于协调多个线程同步执行操作的场合,所有线程等待完成,然后一起做事情( 相互之间都准备好,然后一起做事情 )
例如百米赛跑,必须等待所有运动员都准备好了,才能比赛。
CyclicBarrier cyclicBarrier = new CyclicBarrier(20);for (int i = 0; i < 20; i++) {new Thread(() -> {long timeStamp = System.currentTimeMillis();try {Thread.sleep(new Random().nextInt(2000));System.out.println(Thread.currentThread().getName() + ":一阶段任务完成,花费了" + (System.currentTimeMillis() - timeStamp) + "毫秒,开始等待其他线程");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + ":所有线程执行完成,开始下一阶段");timeStamp = System.currentTimeMillis();Thread.sleep(new Random().nextInt(2000));System.out.println(Thread.currentThread().getName() + ":二阶段任务完成,花费了" + (System.currentTimeMillis() - timeStamp) + "毫秒,开始等待其他线程");cyclicBarrier.await();System.out.println(Thread.currentThread().getName() + ":所有线程任务完成");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}).start();}
Exchanger
交换器顾名思义,就是用来交换数据,理解和使用起来是最简单的,但是内部实现很精巧复杂。使用很简单,只有两个方法,作用就是两个线程在一个安全点交换数据,产生数据慢的那个会阻塞等待。
Exchanger<Integer> exchanger = new Exchanger<>();new Thread(() -> {int num = new Random().nextInt(1000);System.out.println("交换之前:Thread1:" + num);try {num = exchanger.exchange(num);System.out.println("交换完毕:Thread1:" + num);} catch (InterruptedException e) {e.printStackTrace();}}).start();new Thread(() -> {int num = new Random().nextInt(1000);System.out.println("交换之前:Thread2:" + num);try {Thread.sleep(2000);num = exchanger.exchange(num);System.out.println("交换完毕:Thread2:" + num);} catch (InterruptedException e) {e.printStackTrace();}}).start();
Java并发包学习(CountDownLatch,Seamphore,CyclicBarrier,Exchanger)相关推荐
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
2019独角兽企业重金招聘Python工程师标准>>> Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一 ...
- [Java并发包学习八]深度剖析ConcurrentHashMap
转载----http://qifuguang.me/2015/09/10/[Java并发包学习八]深度剖析ConcurrentHashMap/ HashMap是非线程安全的,并发情况下使用,可能会导致 ...
- [Java并发包学习]深度剖析ConcurrentHashMap
[Java并发包学习]深度剖析ConcurrentHashMap 概述 还记得大学快毕业的时候要准备找工作了,然后就看各种面试相关的书籍,还记得很多面试书中都说到: HashMap是非线程安全的,Ha ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
2019独角兽企业重金招聘Python工程师标准>>> 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarr ...
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析
1.简介 在分析完AbstractQueuedSynchronizer(以下简称 AQS)和ReentrantLock的原理后,本文将分析 java.util.concurrent 包下的两个线程同步 ...
- Java并发编程之CountDownLatch、CyclicBarrier和Semaphore
前言 本文为对CountDownLatch.CyclicBarrier.Semaphore的整理使用 CountDownLatch CountDownLatch类位于java.util.concurr ...
- java 并发包学习_Java学习笔记—多线程(java.util.concurrent并发包概括,转载)
一.描述线程的类:Runable和Thread都属于java.lang包 二.内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/noti ...
- 工具资源 Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
内容转载自:http://www.importnew.com/21889.html#comment-636799 转载于:https://www.cnblogs.com/qinshou/p/81196 ...
- 2021年8月12日-------Java从基础到项目教程,Java全栈学习路线,帮你省去培训机构的2万块钱。
余生很贵,请努力活成自己想要的样子. 如何进行学习,别着急,我整理全栈的Java学习路线.帮你吊打面试官. 转载自一位大佬 首先是Java的知识点 一阶段:JavaSE基础 第一步:夯实Java基础语 ...
最新文章
- A Neural Probabilistic Language Model 论文阅读及实战
- iOS性能分析-Xcode Instruments Allocations 分析APP内存使用情况
- 【机器学习】Apriori 算法进行关联分析和FP-growth算法
- 2018-2019-1 20165236《信息安全系统设计基础》第八周学习总结
- 网友反映摩拜单车无法扫码 回应:系技术问题 现已恢复服务
- centos ssh配置使用
- 如何 给给软件开发 添加 代理_如何从“菜鸟码农”变成“一线架构师”?
- 转 常用C#正则表达式收集。
- vs.net已经检测到制定的WEB服务器运行的不是ASP.NET1.1版,你无法运行ASP.NET WEB应用程序或服务...
- 会计计算机学什么软件有哪些,会计一般学什么软件有哪些
- 冰点还原精灵如何安装
- 通过CSS美化Web页面
- VMware Workstation虚拟机环境下Xubuntu系统如何设置中文
- 周集中团队Nature子刊中网络图布局的R语言可视化复现
- 【成功】qlv转MP4,超简单方法
- win、linux、unix查看系统主机名
- 刷脸支付广泛应用于无人领域
- 从微博个性图标里学Android动态更换
- 计算机论文写作提纲怎么写,计算机算法论文提纲 计算机算法论文大纲如何写...
- if语句的三种格式(使你更加清晰)
热门文章
- PHP使用openoffice实现word,ppt,Excel在线转PDF浏览。windows和linux系统不同的解决方案
- ku115上实现adc12dj3200 配置,jesd204b接口,单通道采集模式
- 软件工程(软件计划)
- 视频融合平台EasyCVR首路录像无法播放是什么原因?该如何解决?
- max9286 四合一_MAX9286+HI3519 +MAX96705方案分享
- Android学习笔记:Android基础知识点(不断更新中)
- SAM9X60 curiosity开发板,SYSFS文件系统控制板载三色Led
- Codeforces 1546 D. AquaMoon and Chess —— 组合数学,一点点想法
- 医疗行业售前100问之第2问:医院有几张网?
- 【市场分析1】FinTech之香港虚拟银行VB