Java线程并发常用工具类使用

这次整理了一些比较常用的线程工具类啦。

CountDownLatch:在一组线程执行完后,才能开始执行调用等待的线程。上片文章提到过junit的测试尽量不要测试线程,如果硬是要可以使用CountDownLatch进行测试

CyclicBarrier:在一组线程中调用等待方法后,只有这组所有线程都进入等待后,会执行一个指定的线程,在指定的线程执行完后,这组等待的线程才能继续执行。

Semaphore:可用于限流使用。

Exchanger:当两组线程都执行到交换的方法时,能将数据在这两个线程之间进行数据交换。

CountDownLatch

该类实现主要是由一个内部类Sync实现的,Sync继承了AbstractQueuedSynchronizer(就是经常提到的AQS),

常用的方法有两个:

1.await():线程调用该方法进入带阻塞状态,只有当调用countDown()并骤减到0的时候,才能继续执行

2.countDown():线程骤减一个单位。

具体实现:

 

public class CountDownLatchMain {static CountDownLatch latch = new CountDownLatch(6);static class InitThread implements Runnable{public void run() {try {TimeUnit.MILLISECONDS.sleep(200L);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Thread name:"+Thread.currentThread().getName()+" init ...");latch.countDown();}}static class BusinessThread implements Runnable{public void run() {try {latch.await();} catch (InterruptedException e1) {e1.printStackTrace();}for(int i=0;i<3;i++) {try {TimeUnit.MILLISECONDS.sleep(100L);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread name : " + Thread.currentThread().getName()+" work_" + i);}}}public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {public void run() {latch.countDown();System.out.println("thread name "+Thread.currentThread().getName()+" 1st init ...");try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}latch.countDown();System.out.println("thread name "+Thread.currentThread().getName()+" 2nd init ...");}},"Thread-0").start();new Thread(new BusinessThread()).start();for(int i=0;i<=4 ;i++) {new Thread(new InitThread()).start();}latch.await();TimeUnit.MILLISECONDS.sleep(300);System.out.println("main end ...");}
}

 执行结果:

thread name Thread-0 1st init ...
Thread name:Thread-1 init ...
Thread name:Thread-3 init ...
Thread name:Thread-2 init ...
Thread name:Thread-5 init ...
Thread name:Thread-4 init ...
Thread name : Thread-0 work_0
Thread name : Thread-0 work_1
Thread name : Thread-0 work_2
main end ...
thread name Thread-0 2nd init ...

CyclicBarrier

 

与CountDownLatch差不多,都是等待线程执行完后,才能继续执行,不过这两个不同的地方就是:CountDownLatch需要手动在逻辑代码中进行骤减,减到临界点后,阻塞的线程会继续执行,而CountDownLatch是一组线程都进入到阻塞状态后,然后执行指定线程执行完后,那组阻塞的线程才能继续执行。 示例:

public class CyclicBarrierMain {static CyclicBarrier barrier = new CyclicBarrier(5,new Runnable() {public void run() {System.out.println("Thread name : " + Thread.currentThread().getName() + " barrier start...");try {TimeUnit.MILLISECONDS.sleep(100L);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Thread name : " + Thread.currentThread().getName() + " barrier thread ...");}});static class SubThread implements Runnable{public void run() {long sleep = (long) (Math.random()*1000);System.out.println("thread name : " + Thread.currentThread().getName() + " init ...");try {TimeUnit.MILLISECONDS.sleep(sleep);} catch (InterruptedException e) {e.printStackTrace();}try {System.out.println("thread name : " + Thread.currentThread().getName() + " sleep time:"+sleep);barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println("thread name : " + Thread.currentThread().getName() + " end ....");}}public static void main(String[] args) {for(int i =0 ; i<5;i++) {new Thread(new SubThread()).start();}}
}

执行结果:

thread name : Thread-2 init ...
thread name : Thread-4 init ...
thread name : Thread-1 init ...
thread name : Thread-0 init ...
thread name : Thread-3 init ...
thread name : Thread-2 sleep time:405
thread name : Thread-0 sleep time:488
thread name : Thread-1 sleep time:564
thread name : Thread-4 sleep time:777
thread name : Thread-3 sleep time:860
Thread name : Thread-3 barrier start...
Thread name : Thread-3 barrier thread ...
thread name : Thread-3 end ....
thread name : Thread-2 end ....
thread name : Thread-1 end ....
thread name : Thread-0 end ....
thread name : Thread-4 end ....

Semaphore

 

主要用于需要做限制的场景,比如限制连接池获取次数等等,也有一个Sync内部类继承了AQS

常用方法:

1、acquire():骤减一个单位,也可调用带参的方法可指定减值,当骤减到0的时候,调用该方法会进入阻塞状态。

2、release():释放一个单位,也会在初始化的数量进行增加。

3、availablePermits():得到可获取单位的数量。

4、getQueueLength():调用了acquire()方法并进入到阻塞状态的总数量。

具体用法:

Semaphore semaphore = new Semaphore(5);
semaphore.acquire();//也可指定减少多个semaphore.acquire(2);
//...第6个acquire()方法时,再次调用将进入等待,直到在某个线程中执行了semaphore.release()方法才会继续执行后面的
//...

Exchanger

主要用于两个线程之间的数据交换,个人觉得这个用处不大,既然看到了这个,也就顺便整理了一下

使用示例:

public class UseExcahnger {static Exchanger<Set<String>> exchanger = new Exchanger<Set<String>>();static class ThreadOne extends Thread{@Overridepublic void run() {Set<String> set = new HashSet<String>();set.add("1");set.add("2");try {System.out.println(Thread.currentThread().getName() + " > set:" + set);Thread.sleep(2000L);Set<String> exchange = exchanger.exchange(set);System.out.println(Thread.currentThread().getName() + " > " + exchange);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}static class ThreadTwo extends Thread{@Overridepublic void run() {Set<String> set = new HashSet<String>();set.add("3");set.add("4");try {System.out.println(Thread.currentThread().getName() + " > set:" + set);Thread.sleep(3000L);Set<String> exchange = exchanger.exchange(set);System.out.println(Thread.currentThread().getName() + " > " + exchange);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static void main(String[] args) {new ThreadOne().start();new ThreadTwo().start();}
}

执行结果为:

Thread-0 > set:[1, 2]
Thread-1 > set:[3, 4]
Thread-1 > [1, 2]
Thread-0 > [3, 4]

Future/FutureTask

这个在之前的提到过,与Callable一起使用,用来做回调的,个人觉得这个与之前的Fork/Join的分而治之有些相似,都是异步同时执行完后将结果返回,然后发现相似之后,回去看了一下源代码

RecursiveActionRecursiveTask<T> 都分别继承了Future接口,而FutureTask也继承了Future、Runnable,所以FutureTask既能作为Callable带有返回结果,也能作为Thread去执行它。

这里就介绍一下类中的一些方法,示例的话可以翻看之前的文章

1、isDone():判断线程是否已结束。

2、boolean cancel(boolean mayInterruptIfRunning):参数为true是中断线程,但是只会发送中断信号,在程序中需要自行判断,参数为false则不会中断,返回值为true,如果线程已结束或未开始则返回false。

3、isCancelled():判断线程是否关闭。

4、get():获取线程返回值。

好啦,就先整理这些啦,后面还有一些还在整理,后期会继续分享的呀,如果有问题烦请各路大佬指出

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/537181.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/537181.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三维图形几何变换算法实验_计算机视觉方向简介 | 深度学习视觉三维重建

点击上方“计算机视觉life”&#xff0c;选择“星标”快速获得最新干货作者&#xff1a; Moonsmilehttps://zhuanlan.zhihu.com/p/79628068本文已由作者授权&#xff0c;未经允许&#xff0c;不得二次转载三维重建意义三维重建作为环境感知的关键技术之一&#xff0c;可用于自动…

读《高效程序员的45个习惯——敏捷开发修炼之道》

本书主要用平易的语言讲述了45个有助于提高程序员自身敏捷的习惯&#xff0c;个人感觉这种老外写的书翻译成中文就少了很多意思。 主要的45个习惯是&#xff1a; 做事欲速则不达对事不对人排除万难跟踪变化对团队投资懂得丢弃打破沙锅问到底把握开发节奏让客户做决定让设计指导…

Java线程CAS原子操作

这次分享一些关于原子操作(CAS)的东西. 定义 CAS(Compare And Swap)是CPU的一个指令级别的操作&#xff0c;叫原子操作&#xff0c;原子操作是不可分割的&#xff0c;跟事务差不多&#xff0c;要么全部执行完成&#xff0c;要么不执行&#xff1b; 像这种操作有点类似阻塞锁…

python 导航栏_解析导航栏的url--selnium,beautifulsoup实战

前段时间做ui自动化测试的时候&#xff0c;导航栏菜单始终有点问题&#xff0c;最后只好直接获取到url&#xff0c;然后直接使用driver.get(url)进入页面&#xff1b;包括做压测的时候&#xff0c;比如我要找出所有报表菜单的url&#xff0c;这样不可能手动去一个一个找出来&am…

PNG图片详解

1、PNG图片类型 PNG格式有8位、24位、32位三种&#xff0c;下面是一些术语&#xff1a; 索引透明&#xff1a;类似于GIF&#xff0c;某一像素只有全透和全不透明两种效果Alpha透明&#xff1a;半透明PNG8 8位的PNG最多支持256&#xff08;2的8次方&#xff09;种颜色&#xff0…

Java并发编程之显式锁(Lock)使用

又是一个基于AQS好用的类&#xff0c;看来下次有必要看看AQS了&#xff0c;正好又是放假。 既然叫显式锁&#xff0c;必然也有隐式锁&#xff0c;也就是所谓的synchronzied关键字&#xff0c;它们两者的区别呢在于使用范围&#xff0c;synchronzied关键字的使用范围比Lock要小…

python pychart三维_详解python模块pychartdir安装及导入问题

在迁移别人写好的脚本时&#xff0c;发现pychartdir没有导入&#xff0c;脚本执行报错。以下是报错内容&#xff1a;[modpsLGJF-ZYC5-MMSC-WEB02 ~]$ python /opt/aspire/product/modps/mopps/shell/dayreport_linux.py/etc/host.conf: line 1: bad command nospoof on"Tr…

vim 中Ctags的安装和使用

Ctags是一个用来为源文件中的标识符&#xff08;如变量、函数、类成员、宏定义等&#xff09;创建索引文件的程序。这些tags文件能被编辑器或其它工具用来快速查找定位源代码中的符号&#xff08;tag/symbol&#xff09;&#xff0c;如变量名&#xff0c;函数名等。 Tags文件中…

Java并发编程之AbstractQueuedSynchronizer(AQS)源码解析

自己一个人随便看看源码学习的心得&#xff0c;分享一下啦&#xff0c;不过我觉得还是建议去买本Java并发编程的书来看会比较好点&#xff0c;毕竟个人的理解有限嘛。 独占锁和共享锁 首先先引入这两个锁的概念&#xff1a;独占锁即同一时刻只有一个线程才能获取到锁&#xf…

采集用python还是火车头_我才知道爬虫也可以酱紫--火车采集器

我才知道爬虫还可以这样—火车采集器的使用说在前面额。。。好吧&#xff0c;我这一个三毛钱的屌丝也开始步入实习阶段了&#xff0c;在北京其实也挺好的&#xff0c;虽说压力大&#xff0c;但是今后就业机会也相对而言大一些。好了&#xff0c;说回今天的主题&#xff0c;之前…

mvn 使用中的错误

出现这种错误的时候&#xff1a;mvn Error building POM may not be this projects POM&#xff0c;报的是那个jar 包&#xff0c;就删除那个jar 包&#xff0c;重新mvn clean install .ok

Java并发编程之FutureTask源码解析

上次总结一下AQS的一些相关知识&#xff0c;这次总结了一下FutureTask的东西&#xff0c;相对于AQS来说简单好多呀 之前提到过一个LockSupport的工具类&#xff0c;也了解一下这个工具类的用法&#xff0c;这里也巩固一下吧 /*** Makes available the permit for the given th…

java 删除二维数组中的null_避免在Java中检查Null语句

1.概述通常&#xff0c;在Java代码中处理null变量、引用和集合很棘手。它们不仅难以识别&#xff0c;而且处理起来也很复杂。事实上&#xff0c;在编译时无法识别处理null的任何错误&#xff0c;会导致运行时NullPointerException。在本教程中&#xff0c;我们将了解在Java中检…

Java并发编程之并发容器ConcurrentHashMap(JDK1.7)解析

最近看了一下ConcurrentHashMap的相关代码&#xff0c;感觉JDK1.7和JDK1.8差别挺大的&#xff0c;这次先看下JDK1.7是怎么实现的吧 哈希&#xff08;hash&#xff09; 先了解一下啥是哈希&#xff08;网上有很多介绍&#xff09;&#xff0c;是一种散列函数&#xff0c;简单来…

带控制端的逻辑运算电路_分别完成正整数的平方、立方和阶乘的运算verilog语言...

练习&#xff1a;设计一个带控制端的逻辑运算电路&#xff0c;分别完成正整数的平方、立方和阶乘的运算。 //--------------myfunction---------- modulemyfunction(clk,n,result,reset,sl); output[6:0]result; input[2:0] n; input reset,clk; input [1:0] sl; reg[6:0]resul…

Java并发编程之并发容器ConcurrentHashMap(JDK1.8)解析

这个版本ConcurrentHashMap难度提升了很多&#xff0c;就简单的谈一下常用的方法就好了&#xff0c;可能有些讲的不太清楚&#xff0c;麻烦发现的大佬指正一下 主要数据结构 1.8将Segment取消了&#xff0c;保留了table数组的形式&#xff0c;但是不在以HashEntry纯链表的形式…

simulink显示多个数据_如何在 Simulink 中使用 PID Tuner 进行 PID 调参?

作者 | 安布奇责编 | 胡雪蕊出品 | CSDN(ID: CSDNnews)本文为一篇技术干货&#xff0c;主要讲述在Simulink如何使用PID Tuner进行PID调参。PID调参器( PIDTuner)概述1.1 简介使用PID Tuner可以对Simulink模型中的PID控制器&#xff0c;离散PID控制器&#xff0c;两自由度PID控制…

Java并发编程之堵塞队列介绍以及SkipList(跳表)

堵塞队列 先了解一下生产者消费者模式&#xff1a; 生产者就是生产数据的一方&#xff0c;消费者就是消费数据的另一方。在多线程开发中&#xff0c;如果生产者处理速度很快&#xff0c;而消费者处理速度很慢&#xff0c;那么生产者就必须等待消费者处理完&#xff0c;才能继…

python生成list的时候 可以用lamda也可以不用_python 可迭代对象,迭代器和生成器,lambda表达式...

分页查找#5.随意写一个20行以上的文件(divmod)# 运行程序&#xff0c;先将内容读到内存中&#xff0c;用列表存储。# l []# 提示&#xff1a;一共有多少页# 接收用户输入页码&#xff0c;每页5条&#xff0c;仅输出当页的内容def read_page(bk_list,n,endlineNone):startline …

数据挖掘技术简介[转]

关键词&#xff1a; 关键词&#xff1a;数据挖掘 数据集合 1. 引言  数据挖掘(Data Mining)是从大量的、不完全的、有噪声的、模糊的、随机的数据中提取隐含在其中的、人们事先不知道的、但又是潜在有用的信息和知识的过程。随…