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接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...
随机推荐
- post传参params与body的区别(@RequestParam和@RequestBody的区别)
1.axios post请求 Content-Type默认为 application/x-www-form-urlencoded,我们传递参数的时,params里面的参数(简单的对象,通过 &quo ...
- HTML5(五)——Canvas API
什么是 Canvas API? Canvas API(画布)提供了一个通过 javascript 和 html 的 canvas 元素来在网页上实时绘制图形的方式.可用于动画.游戏.图标.图片编辑等多 ...
- 🔥 LeetCode 热题 HOT 100(31-40)
75. 颜色分类 思路:将 2 往后放,0 往前放,剩余的1自然就放好了. 使用双指针:left.right 分别指向待插入的 0 和 2 的位置,初始 left 指向数组头,right 指向数组尾部 ...
- 2020厦门大学综述翻译:3D点云深度学习(Remote Sensiong期刊)
目录 摘要 1.引言: 2.点云深度学习的挑战 3.基于结构化网格的学习 3.1 基于体素 3.2 基于多视图 3.3 高维晶格 4.直接在点云上进行的深度学习 4.1 PointNet 4.2 局部 ...
- Spring Cloud分区发布实践(1) 环境准备
最近研究了一下Spring Cloud里面的灰度发布, 看到各种各样的使用方式, 真是纷繁复杂, 眼花缭乱, 不同的场景需要不同的解决思路. 那我们也来实践一下最简单的场景: 区域划分: 服务分为be ...
- Docker限制
前言 Docker系列文章: 此篇是Docker系列的第十篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,马上就开始Kubernetes,加油!一起前行! 为什么要学习Docker Do ...
- Salesforce Integration 概览(三) Remote Process Invocation—Fire and Forget(远程进程调用-发后即弃)
本篇参考:https://resources.docs.salesforce.com/sfdc/pdf/integration_patterns_and_practices.pdf 我们在上一篇讲了远 ...
- C++1-100之间 7的倍数 带7 打印 敲桌子
1 // 1-100之间 7的倍数 带7 打印 敲桌子 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 ...
- 【笔记】求数据前n个主成分以及对高维数据映射为低维数据
求数据前n个主成分并进行高维数据映射为低维数据的操作 求数据前n个主成分 先前的将多个样本映射到一个轴上以求使其降维的操作,其中的样本点本身是二维的样本点,将其映射到新的轴上以后,还不是一维的数据,对 ...
- RocketMQ可视化控制台
中午文档 https://github.com/apache/rocketmq-externals/blob/master/rocketmq-console/doc/1_0_0/UserGuide_C ...