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) ...
随机推荐
- vue+django分离开发的思想和跨域问题的解决
一.介绍 在前后端分离的开发过程中,会涉及到跨域的问题,比如本次个人使用的Django+vue的框架,在vue对Django进行响应,Django再将响应的数据返回给vue,vue在进行渲染,如果不设 ...
- 【题解】Informacije [COCI2012]
[题解]Informacije [COCI2012] 传送门:官方题面 [题目描述] 有一个长度为 \(n\) 的 序列 \(a\)(由 \([1,n]\) 中的数组成,且每个数只会出现一次),现给出 ...
- Immediate Window
name="ZFF""ZFF"date=new DateTime(2017,02,03,21,19,45){2/3/2017 21:19:45 PM} Date ...
- GDAL读取Shapefile
-------------------------------------------------------------------------------------- #include < ...
- runtime template in vuejs
在使用vuejs开发的过程中,有时候我们需要动态模板的场景,也就是说模板并不是静态定义好的,而是动态变化的. 比如在做一个所见所得编辑器时,编辑人员可能时刻需要调整他设计的页面内容,而如果页面内容包含 ...
- Java基础—实现多线程的三种方法
Java虚拟机(JVM,是运行所有Java程序的抽象计算机,是Java语言的运行环境)允许应用程序并发地运行多个线程.在Java语言中,多线程的实现一般有以下三种方法: 1.实现Runnable接口, ...
- vue中使用axios进行ajax请求数据(跨域配置)
npm安装axios npm install axios --save 引入axios import axios from 'axios' 使用axios mounted () { this.getH ...
- django更换ORM连接处理(连接池)转
1 概述 在使用 Django 进行 Web 开发时, 我们避免不了与数据库打交道. 当并发量低的时候, 不会有任何问题. 但一旦并发量达到一定数量, 就会导致 数据库的连接数会被瞬时占满. 这将导致 ...
- 基本SQL语句使用方法
结构:增: create database 库名 charset 字符集: create table 表名称(字段名 类型 约束 ,字段名 类型 约束) not null 非空primary key ...
- HDU 1241 Oil Deposits 题解
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...