Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
CountDownLatch
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
CountDownLatch中的方法
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
CountDownLatchDemo
条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(20);
//条件改为i<20时,并不会输出“完结撒花”,因为latch还没有减到0
for (int i = 0; i < 20; i++) {
int index=i;
new Thread(new Runnable() {
@Override
public void run() {
latch.countDown();
System.out.println(index);
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完结撒花");
}
}
CyclicBarrier
CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。
- CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
构造方法
public CyclicBarrier(int parties)
public CyclicBarrier(int parties, Runnable barrierAction)
- parties 是参与线程的个数
- 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务
方法
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
- 线程调用 await() 表示自己已经到达栅栏
- BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时
Demo
- 初始化线程1,线程1睡眠3秒
- 剩余九个线程到达barrier,但是并不会又输出
- 三秒后线程1到达,9个线程开始输出
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(10);
//初始化线程1,线程1睡眠3秒,等待剩余九个线程到达barrier
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
//九个线程先到达barrier
for (int i = 0; i < 9; i++) {
int index=i;
new Thread(new Runnable() {
@Override
public void run() {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(index);
}
}).start();
}
}
}
//Output,输出是随机的
/*
0
6
2
1
8
7
4
3
5*/
Semaphore
Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。
常用方法
void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
void release():释放一个许可,将其返回给信号量。
int availablePermits():返回此信号量中当前可用的许可数。
boolean hasQueuedThreads():查询是否有线程正在等待获取。
Demo
- 六个人竞争三个办事窗口,每个办事窗口只能容纳三个人,输出如下
package ConcurrentApi;
import java.util.concurrent.Semaphore;
//Output
/*
线程0等到了办事窗口空闲
办事窗口剩余量2
线程1等到了办事窗口空闲
办事窗口剩余量1
线程2等到了办事窗口空闲
办事窗口剩余量0
线程3等到了办事窗口空闲
办事窗口剩余量0
线程4等到了办事窗口空闲
办事窗口剩余量0
线程5等到了办事窗口空闲
办事窗口剩余量0*/
public class SemaphoreDemo {
public static void main(String[] args) {
//初始化3 三个办事窗口
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 6; i++) {
int index = i;
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("线程"+index+"等到了办事窗口空闲");
System.out.println("办事窗口剩余量"+semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
}
}).start();
}
}
}
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo的更多相关文章
- java并发编程工具类辅助类:CountDownLatch、CyclicBarrier和 Semaphore
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
- java并发编程工具类JUC第四篇:LinkedBlockingQueue链表队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue. LinkedBlockingQueue 队列是Blo ...
- java并发编程工具类JUC第七篇:BlockingDeque双端阻塞队列
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程工具类JUC第八篇:ConcurrentHashMap
在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口.ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.Priorit ...
- java并发编程工具类JUC第一篇:BlockingQueue阻塞队列
Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...
- java并发编程工具类JUC第三篇:DelayQueue延时队列
DelayQueue 是BlockingQueue接口的实现类,它根据"延时时间"来确定队列内的元素的处理优先级(即根据队列元素的"延时时间"进行排序).另一层 ...
- java并发编程工具类JUC第二篇:ArrayBlockingQueue
类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...
随机推荐
- Python3中datetime时区转换介绍与踩坑
最近的项目需要根据用户所属时区制定一些特定策略,学习.应用了若干python3的时区转换相关知识,这里整理一部分记录下来. 下面涉及的几个概念及知识点: GMT时间:Greenwich Mean Ti ...
- Netty入门(一):ByteBuf
网络数据的基本单位总是字节.Java NIO 提供了 ByteBuffer 作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐.Netty 的 ByteBuffer 替代品是 ByteBuf ...
- SprintBoot简单入门
1.什么是SpringBoot SpringBoot是基于Spring的基础上提供了一套全新的框架,其目的是为了在开发时简化Spring的相关配置及开发过程.在SpringBoot未出来之前,准备搭建 ...
- JVM的内存管理机制-转载
JVM的内存管理机制 一.JVM的内存区域 对于C.C++程序员来说,在内存管理领域,他们既拥有每一个对象的"所有权",又担负着每一个对象生命开始到终结的维护责任. 对Java程序 ...
- CentOS 7 安装虚拟机
1.本次安装centos7 安装使用的软件是VitrualBox 虚拟机软件 Oracle公司的虚拟机软件,免费商品(大家可以百度搜索去官网下载) 1:我这里使用的是阿里的centos7的镜像(大家可 ...
- 卷向字节码-Java异常到底是怎么被处理的?
你好呀,我是why,你也可以叫我歪歪. 比如下面这位读者: 他是看了我<神了!异常信息突然就没了?>这篇文章后产生的疑问. 既然是看了我的文章带来的进一步思考,恰巧呢,我又刚好知道. 虽然 ...
- Java流程控制03——选择结构
选择结构 if单语句结构 我们很多时候要去判断一个东西是否可行,然后我们才去执行,这样一个过程我们用if语句来表示 语法 if(布尔表达式){ //如果布尔表达式结果为true将执行的语句 } if ...
- 第一个Java文件
HelloWorld 1.新建一个文件夹,用来存放java文件的 2.用subline来编辑第一个Java文件 要注意的是java的文件名为.java 我们自定义的文件名是Hello 3.编写第一个j ...
- .NET 6 预览版 7:新功能已完成 ,将专注于改进
.NET 团队的项目经理 Richard Lander在宣布 .NET 6 Preview 7 时说:"这是 .NET 预览的又一季的结束.", 中文翻译:.NET 6 预览版 7 ...
- 【笔记】Stacking方法
Stacking 先前学习的集成学习 先前的思路很简单,假设有三个算法,每个算法都对数据进行一个预测,最后综合这三个结果得出一个最终结果,对于分类问题可以进行少数服从多数,对于回归问题可以简单地取平均 ...