Java多线程(八)——多线程辅助功能类
目录
一、引言
二、Semaphore
三、countdownlatch
四、cyclicbarrier
五、exchanger
六、总结
一、引言
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier、Semaphore和exchanger。
Semaphore:一个计数信号量
CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点
Exchanger:方便了两个共同操作线程之间的双向交换
下面举例子分别介绍这些类的使用场景
二、Semaphore
Semaphore 信号量对象管理的信号就像令牌,构造时传入个数,总数就是控制并发的数量。我们需要控制并发的代码,执行前先获取信号(通过acquire获取信号许可),执行后归还信号(通过release归还信号许可)。每次acquire成功返回后,Semaphore可用的信号量就会减少一个,如果没有可用的信号,acquire调用就会阻塞,等待有release调用释放信号后,acquire才会得到信号并返回。
如果Semaphore管理的信号量为1个,那么就退化到互斥锁了;如果多于一个信号量,则主要用于控制并发数。与通过控制线程数来控制并发数的方式相比,通过Semaphore来控制并发数可以控制得更加细粒度,因为真正被控制最大并发的代码放到acquire和release之间就行了。
使用场景,食堂做饭只有四个切菜刀,有十个人要切十个菜,限制菜刀数量抢到的先切菜,切完再给别人。
public class Testsemophore {public static void main(String[]args){final Semaphore semaphore = new Semaphore(3);for (int i=0;i<7;i++){new Thread(new Runnable() {public void run() {try {semaphore.acquire();System.out.println(Thread.currentThread().getName()+"获取到许可");Thread.sleep(1000);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}}).start();}}}
输出结果:
Thread-0获取到许可
Thread-2获取到许可
Thread-1获取到许可
Thread-3获取到许可
Thread-4获取到许可
Thread-5获取到许可
Thread-6获取到许可
三、countdownlatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
其机制是:当多个(具体数量等于初始化CountDownLatch时的count参数的值)线程都达到了预期状态或完成预期工作时触发事件,其他线程可以等待这个事件来触发自己的后续工作。这里需要注意的是,等待的线程可以是多个,即CountDownLatch是可以唤醒多个等待的线程的。达到自己预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法。
CountDownLatch 很适合用来将一个任务分为n个独立的部分,等这些部分都完成后继续接下来的任务,CountDownLatch 只能出发一次,计数值不能被重置。
public class Testcutdownlatch {public static void main(String[] args) {final CountDownLatch latch = new CountDownLatch(3);new Thread(new Runnable() {public void run() {try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Waiter Released");}}).start();new Thread(new Runnable() {public void run() {try {Thread.sleep(1000);latch.countDown();Thread.sleep(1000);latch.countDown();Thread.sleep(1000);latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}}).start();}}
输出结果:
Waiter Released
四、cyclicbarrier
可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作。
CyclicBarrier适用于多个线程有固定的多步需要执行,线程间互相等待,当都执行完了,再一起执行下一步。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier
public class Testcyclicbarrier {public static void main(String[] args) {final CyclicBarrier barrier1 = new CyclicBarrier(2, new Runnable() {public void run() {System.out.println("BarrierAction 1 executed ");}});final CyclicBarrier barrier2 = new CyclicBarrier(2, new Runnable() {public void run() {System.out.println("BarrierAction 2 executed ");}});for (int i=0;i<3;i++){new Thread(new Runnable() {public void run() {try {Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+"waited barrier1");barrier1.await();Thread.sleep(1000);System.out.println(Thread.currentThread().getName()+"waited barrier2");barrier2.await();} catch (InterruptedException e) {e.printStackTrace();}catch (BrokenBarrierException e) {e.printStackTrace();}}}).start();}}}
输出结果:
Thread-0waited barrier1
Thread-2waited barrier1
Thread-1waited barrier1
BarrierAction 1 executed
Thread-0waited barrier2
Thread-1waited barrier2
BarrierAction 2 executed
注意比较CountDownLatch和CyclicBarrier:
(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。
CountDownLatch 适用于一组线程和另一个主线程之间的工作协作。一个主线程等待一组工作线程的任务完毕才继续它的执行是使用 CountDownLatch 的主要场景;CyclicBarrier 用于一组或几组线程,比如一组线程需要在一个时间点上达成一致,例如同时开始一个工作。
五、exchanger
Exchanger 类方便了两个共同操作线程之间的双向交换;这样,就像具有计数为 2 的 CyclicBarrier,并且两个线程在都到达屏障时可以“交换”一些状态。(Exchanger 模式有时也称为聚集。)
Exchanger 通常用于一个线程填充缓冲(通过读取 socket),而另一个线程清空缓冲(通过处理从 socket 收到的命令)的情况。当两个线程在屏障处集合时,它们交换缓冲。
public class Testexchanger {public static void main(String[]args){final Exchanger exchanger = new Exchanger();//Action action=new Action();new Thread(new Runnable() {public void run() {try {Thread.sleep(1000);exchanger.exchange(Thread.currentThread().getName()+"data");System.out.println(Thread.currentThread().getName()+"我交给你了");} catch (InterruptedException e) {e.printStackTrace();}}}).start();new Thread(new Runnable() {public void run() {try {exchanger.exchange(Thread.currentThread().getName()+"data");System.out.println(Thread.currentThread().getName()+"我交给你了");} catch (InterruptedException e) {e.printStackTrace();}}}).start();}}
输出结果:
Thread-0我交给你了
Thread-1我交给你了
六、总结
- semaphore
- countdownlatch
- cyclicbarrier
- exchanger
Java多线程(八)——多线程辅助功能类相关推荐
- java知识点八:时间日期类
时间日期类 一.常用日期类 1.System类 2.Date类 3.SimpleDateFormat类 4.Calendar类 二.System类 比较常用的相关方法currentTimeMills( ...
- 详解Java多线程编程中LockSupport类的线程阻塞用法
转载自 详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际 ...
- java thread类_Java多线程原理及Thread类详解
多线程原理 代码如下: 自定义线程类: 测试类: 流程图: 程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建.随着调用mt的对象的start方法,另外一 ...
- JAVA中的多线程(八):线程的优先级和yield方法
JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...
- JavaSE基础二十:Java 多线程(线程基础知识、Java 多线程、Java 实现多线程(继承 Thread 类、实现 Runnable 接口、实现 Callable 接口))
本章目录 1.基础知识准备 2.Java 多线程概述 3.Java 实现多线程 3.1.继承 Thread 类 如何开启新线程 Thread 类常用方法 多线程中的同步 Thread 类同步方法 多线 ...
- 基于Java多线程的打怪升级类游戏设计与开发
摘要:本文论述了通过JAVA多线程.基于JAVA Swing的GUI图形用户界面设计.IO输入输出流.JDBC技术,实现了游戏系统的UI设计.游戏数据的存储.关卡的设置.用户头像的上传与更改.游戏数据 ...
- java里的多线程同步机制
2019独角兽企业重金招聘Python工程师标准>>> 要说明线程同步问题首先要说明Java线程的两个特性,可见性和有序性.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通 ...
- Java并发与多线程
1.多线程优点 资源利用率更好:文件读写操作 程序设计在某些情况下更简单: 程序响应更快:端口监听操作 2.多线程的代价 设计更复杂:多线程共享数据时尤其需要注意 上下文切换的开销: CPU 会在一个 ...
- Java基础21 多线程线程两种实现方式 锁
一.多线程的概念 1.程序 :一个固定逻辑与数据的集合 就称为程序 例如淘宝 贪吃蛇小游戏 2.CPU: 中央处理器 主要用于协调程序与硬件进行配置的工作 3.并发与并行 1.并发(高并发) 在同一个 ...
- JAVA 笔记 10 多线程
进程 与 线程 进程 进程资源分配的最小单位,CPU从磁盘中读取一段程序到内存中,该执行程序的实例就叫做进程; 一个程序如果被CPU多次读取到内存中,则变成多个独立的进程. 线程 线程是程序执行的最小 ...
最新文章
- TSNE-原理与实现
- 使用JConsole监控ActiveMQ
- 今天写了个Win32服务设置软件,呵呵,纯绿色软件
- [007] 详解 .NET 程序集
- 一个不错的讲解flex 3中自定义事件的文章
- mysql 子字符串函数_MySQL 内置字符串函数
- linux下为php开启oci8扩展(ubuntu14亲测可用)
- C# 获取项目程序路径的10种方法
- IDM(Internet Download Manager)下载各类安装包(github代码、python包)、软件、视频、文档的神器,居家必备良药
- python 正则处理经纬度度分秒转换
- javascript跨域
- 无本经营?2021做电商跨境shopee平台赚钱很轻松!
- MIPI CSI、DSI、UFS、C-PHY、D-PHY、M-PHY概念理解
- android突然断电丢失程序,a2sd+状态下应用程序丢失的解决方法详细解析
- linux怎么让cpu不自动降频,Win10 CPU自动降频怎么办?Win10下让CPU不降频设置方法
- shader拖尾_拖尾效果 - LouisSong - 博客园
- c语言lr分析器的设计与实现_ShinyJson实践之路:词法分析器的设计与实现
- 盘点国内EDA软件公司
- python利用turtle库绘制正方形绕一个顶点旋转
- 构建人工智能评测平台(体系)