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. 参考网址

  1. 参考来源:http://cmsblogs.com/wp-content/resources/img/sike-juc.png
  2. 《Java并发编程的艺术》_方腾飞PDF 提取码:o9vr
  3. http://ifeve.com/the-art-of-java-concurrency-program-1/
  4. Java并发学习系列-绪论
  5. Java并发编程实战
  6. 死磕 Java 并发精品合集

Java 并发系列之八:java 并发工具(4个)的更多相关文章

  1. java并发系列(八)-----java异步编程

    同步计算与异步计算 从多个任务的角度来看,任务是可以串行执行的,也可以是并发执行的.从单个任务的角度来看,任务的执行方式可以是同步的,也可以是异步的. Runnable.Callable.Future ...

  2. 【Java并发系列】--Java内存模型

    Java内存模型 1 基本概念 程序:代码,完成某一个任务的代码序列(静态概念) 进程:程序在某些数据上的一次运行(动态) 线程:一个进程有一个或多个线程组成(占有资源的独立单元) 2 JVM与线程 ...

  3. java并发系列(六)-----Java并发:volatile关键字解析

    在 Java 并发编程中,要想使并发程序能够正确地执行,必须要保证三条原则,即:原子性.可见性和有序性.只要有一条原则没有被保证,就有可能会导致程序运行不正确.volatile关键字 被用来保证可见性 ...

  4. ☕【Java深层系列】「并发编程系列」深入分析和研究MappedByteBuffer的实现原理和开发指南

    前言介绍 在Java编程语言中,操作文件IO的时候,通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java nio中引入了一种基于Mapp ...

  5. 【java虚拟机系列】java虚拟机系列之JVM总述

    我们知道java之所以能够快速崛起一个重要的原因就是其跨平台性,而跨平台就是通过java虚拟机来完成的,java虚拟机属于java底层的知识范畴,即使你不了解也不会影响绝大部分人从事的java应用层的 ...

  6. 【java多线程系列】java内存模型与指令重排序

    在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...

  7. Java Web系列:Java Web 项目基础

    1.Java Web 模块结构 JSP文件和AXPX文件类似,路径和URL一一对应,都会被动态编译为单独class.Java Web和ASP.NET的核心是分别是Servlet和IHttpHandle ...

  8. 【java开发系列】—— java输入输出流

    前言 任何语言输入输出流都是很重要的部分,比如从一个文件读入内容,进行分析,或者输出到另一个文件等等,都需要文件流的操作.这里简单介绍下reader,wirter,inputstream,output ...

  9. Java多线程系列一——Java实现线程方法

    Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2) ...

随机推荐

  1. HDU 1723 Distribute Message DP

    The contest’s message distribution is a big thing in prepare. Assuming N students stand in a row, fr ...

  2. 使用NumPy、Numba的简单使用(一)

    Numpy是python的一个三方库,主要是用于计算的,数组的算数和逻辑运算.与线性代数有关的操作. 很多情况下,我们可以与SciPy和 Matplotlib(绘图库)一起使用.来替代MatLab,下 ...

  3. dedecms5.7的文章详情页页面标题加载指定txt文本的随机关键字

    dedecms5.7的文章详情页加载指定txt文本的随机关键字 1 实现代码如下 {dede:name runphp='yes'} $file_path = "../test.txt&quo ...

  4. 百度编辑器UEditor,保存图片的配置问题

    前言: 在使用百度编辑器UEditor的时候,如何将图片保存到服务器,我刚开始以为是要自己写上传文件的方法,后来发现只需要配置一下即可,如果你也正在使用百度富文本编辑器UEditor的话,这篇文章将非 ...

  5. 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP)

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

  6. Vue内置组件[回顾]

    1.动态组件 在某些场景,往往需要我们动态切换页面部分区域的视图,这个时候内置组件component就显得尤为重要. component接收一个名为is的属性,is的值应为父组件中注册过的组件的名称, ...

  7. linux清屏

    clear 这个命令将会刷新屏幕,本质上只是让终端显示页向后翻了一页,如果向上滚动屏幕还可以看到之前的操作信息 reset 这个命令将完全刷新终端屏幕,之前的终端输入操作信息将都会被清空,这样虽然比较 ...

  8. iOS 快速打包方法

    这种打包方式应该是目前所有打包方式中最快的,就是编译工程--找到.app文件--新建Payload文件夹--拷贝.app到Payload文件夹--压缩成zip--更改后缀名为ipa--完成! 注意事项 ...

  9. 使用python来反查数据表中的字段名

    1. 链接数据库 import psycopg2 conn = psycopg2.connect(user,host,port,database,password) cur = conn.cursor ...

  10. Python中创建虚拟环境(virtualenv模块)

    针对环境:win7,python2.7 需要virtualenv模块1.测试是否已安装virtualenv模块    import virtualenv  #没有报错则已安装    否则需要先安装vi ...