Java 并发系列之八:java 并发工具(4个)
1. CountDownLatch
2. CyclicBarrier
3. Semaphore
4. Exchanger
5. txt
java 并发工具
通俗理解
CountDownLatch
等ABCD 4个人都结束了,自己才能开始,结束一个减一个
CyclicBarrier
我和A,B,C,D 5个人互相等待,会合了再一起进电影院,到一个减一个
Semaphore
计数器,鸡蛋篮子里只能放5个鸡蛋,缺几个,才能放几个
Exchanger
A和B交换数据
CountDownLatch
CountDownLatch 它允许一个或多个线程等待其他N个指定数量线程完成操作
CountDownLatch也可以实现join的功能,并且比join的功能更多
AQS(队列同步器) 共享锁
内部类
sync为CountDownLatch的一个内部类,而Sync继承AQS。
采用共享锁来实现的。
重要操作
CountDownLatch(int count)
构造一个用给定计数初始化的 CountDownLatch,count为计数器的初始值,也可以理解为该共享锁可以获取的总次数。
await()
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断
awit(long time, TimeUnit unit)
带指定时间的await方法,这个方法在等待特定时间之后,就不会阻塞当前线程。
countDown()
递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
一个线程调用countDown方法 happen-before 另外一个线程调用 await 方法
注意CountDownLatch不能回滚重置。
CyclicBarrier
定义
可循环使用的同步屏障:它允许一组线程互相等待,直到达到某个公共屏障点(common barrier point)
通俗讲:让一组线程到达一个屏障是被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活
底层采用ReentrantLock + Condition 实现
重要操作
两个构造函数
CyclicBarrier(int parties):parties表示屏障拦截的线程数量(插入的屏障数),每个线程调用await方法告诉CyclicBarrier已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier(int parties, Runnable barrierAction) :用于在线程到达屏障前,优先执行barrierAction,方便处理更复杂的业务场景
其他方法
getNumberWaiting
获得CyclicBarrier阻塞的线程数量
isBrocken
了解阻塞的线程是否被中断
await()
插入屏障,到达了屏障,本质上相当于屏障数-1
应用场景
多线程结果合并的操作,用于多线程计算数据,最后合并计算结果的应用场景
CyclicBarrier V.S. CountDownLatch
CountDownLatch的作用是允许1个或N个线程等待其他线程完成执行;
CyclicBarrier则是允许N各线程互相等待
CountDownLatch的计数器无法被重置,只能使用一次如果需要重置计数,请考虑使用CyclicBarrier.
CyclicBarrier的计数器可以被reset重置后使用,因此它被称为是循环的barrier,能处理更为复杂的业务场景。例如计算发生错误,可以重置计数器,并让线程重新执行一次
Semaphore
信号量
计数器,用来控制同时访问特定资源的线程数量,他通过协调各个线程,以保证合理的使用公共资源
内部采用共享锁实现
信号量Semaphore是一个非负数(>=1)。当一个线程想要访问某个共享资源时,它必须要先获取Semaphore,当Semaphore>0 时,获取该资源并使 Semaphore-1. 如果Semaphore=0,则表示全部的共享资源已经被其他线程全部占用,线程必须要等待其他线程释放资源。当线程释放资源时,Semaphore+1。
从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对许可的号码进行计数,并采取相应的行动。
重要操作
Semaphore(int permits)
构造函数,接受一个整型的数字,表示可用的许可证数量,也就是最大的并发量
acquire
获取一个许可证
tryAcquire
尝试获取一个许可证
release
归还许可证
int availablePermits()
返回此信号量中当前可用的许可证数
int getQueueLength()
返回正在等待获取许可证的线程数
boolean hasQueuedThreads()
是否有线程正在等待获取许可证
void reducePermits(int reduction)
减少reduction个许可证
Collection getQueuedThreads()
返回所有等待获取许可证的线程集合
应用场景
用于流量控制,特别是公用资源有限的应用场景,比如数据库连接。
Exchanger
定义
交换者,是一个用于线程间协作的工具类,用于进行线程间的数据交换,两个线程
它提供一个同步点,用于进行线程间成对配对及交换数据,
具体
第一个线程先执行exchange()方法,它会一只等待第二个线程也执行exchange()方法,当两个线程都到达同步点时,两个线程就可以交换数据,将本线程生产出来的数据传递给对方
允许在并发任务之间交换数据。具体来说,Exchanger类允许在两个线程之间定义同步点。当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中
应用场景
遗传算法
交叉
校对工作
AB岗录入电子银行流水
Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。
6. 参考网址
- 参考来源:http://cmsblogs.com/wp-content/resources/img/sike-juc.png
- 《Java并发编程的艺术》_方腾飞PDF 提取码:o9vr
- http://ifeve.com/the-art-of-java-concurrency-program-1/
- Java并发学习系列-绪论
- Java并发编程实战
- 死磕 Java 并发精品合集
Java 并发系列之八:java 并发工具(4个)的更多相关文章
- java并发系列(八)-----java异步编程
同步计算与异步计算 从多个任务的角度来看,任务是可以串行执行的,也可以是并发执行的.从单个任务的角度来看,任务的执行方式可以是同步的,也可以是异步的. Runnable.Callable.Future ...
- 【Java并发系列】--Java内存模型
Java内存模型 1 基本概念 程序:代码,完成某一个任务的代码序列(静态概念) 进程:程序在某些数据上的一次运行(动态) 线程:一个进程有一个或多个线程组成(占有资源的独立单元) 2 JVM与线程 ...
- java并发系列(六)-----Java并发:volatile关键字解析
在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保证可见性 ...
- ☕【Java深层系列】「并发编程系列」深入分析和研究MappedByteBuffer的实现原理和开发指南
前言介绍 在Java编程语言中,操作文件IO的时候,通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java nio中引入了一种基于Mapp ...
- 【java虚拟机系列】java虚拟机系列之JVM总述
我们知道java之所以能够快速崛起一个重要的原因就是其跨平台性,而跨平台就是通过java虚拟机来完成的,java虚拟机属于java底层的知识范畴,即使你不了解也不会影响绝大部分人从事的java应用层的 ...
- 【java多线程系列】java内存模型与指令重排序
在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...
- Java Web系列:Java Web 项目基础
1.Java Web 模块结构 JSP文件和AXPX文件类似,路径和URL一一对应,都会被动态编译为单独class.Java Web和ASP.NET的核心是分别是Servlet和IHttpHandle ...
- 【java开发系列】—— java输入输出流
前言 任何语言输入输出流都是很重要的部分,比如从一个文件读入内容,进行分析,或者输出到另一个文件等等,都需要文件流的操作.这里简单介绍下reader,wirter,inputstream,output ...
- Java多线程系列一——Java实现线程方法
Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2) ...
随机推荐
- git同步本地数据到github——第一次使用和以后使用
git作为版本控制工具十分的好用,但是在使用的过程中,会因为仓库版本的不同步出现很多错误 一.git简单的原理交互模型 从下面的model中我们看到在不创建分支情况下始终是远程的origin和本地的m ...
- 今日头条3面,被泄露的Java最新面试题
一.面试第 1 轮 1. linux 网络模型 2. b+树 3. 阻塞队列 4. redis 和 MongoDB 的区别.几个概念对比,还有底层实现. 5. 算法题: merge k sorted ...
- mask-rcnn代码解读(七):display(self)函数的解析
如和将class中定义的变量打印或读取出来,受maskrcnn的config.py的启示,我将对该函数进行解释. 我将介绍该函数前,需要对一些名词进行解释,如下: ①Ipython:ipython是一 ...
- C通过JNI反向调用JAVA程序方法
JNI反向调用JAVA程序 引述:上文讲过java线程---OS线程的关系,然后C怎样反向调用JAVA程序方法是我们这篇讲的重点 1.ThreadTest中添加run()方法 2.编译ThreadTe ...
- es6中find方法
find() 方法返回数组中满足提供的测试函数的第一个元素的值.否则返回 undefined. , , , , ]; var found = array1.find(function(element) ...
- java实现word生成并转pdf
前言 本篇博客主要解决java后台动态生成word(docx格式),并将word转换为pdf并添加水印. 思考 项目需求是要导出带水印的pdf,表格样式还是有点复杂的,之前考虑过用itextpdf根据 ...
- leetcode - 链表两两元素交换 + 判断链表有无环
链表两两元素交换 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例: 给定 1->2->3->4, 你 ...
- Spark(4)
Spark Core官网学习回顾 Speed disk 10x memory 100x Easy code interactive shell Unified Stack Batch Streamin ...
- MongoDB 4.X 用户和角色权限管理总结
关于MongoDB的用户和角色权限的梳理一直不太清晰,仔细阅读了下官方文档,并对此做个总结. 默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随 ...
- STM32F4 串口IAP程序要点
1. IAP(bootloader)程序 1.1 内部Flash地址分配 /* Start of the Flash address */ #define STM32_FLASH_BASE 0x080 ...