juc包下四大并发工具
juc.CountDownLatch 闭锁
一个线程在等待一组线程后再恢复执行
await()等待其他线程执行完毕
被等待线程执行完毕后计数器-1
如何知道其他线程执行完了?
计数器,若一组线程为,CountDown为5,减到0代表等待线程被全部执行完毕
一次性工具:当Countdown的值减到0的时候再也无法恢复
juc内部的代码都是lock体系来实现的
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; // 运动员线程
class CDLTask implements Runnable {
private CountDownLatch countDownLatch; public CDLTask(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始跑步");
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()+"到达终点");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(4);
CDLTask cdlTask = new CDLTask(countDownLatch);
System.out.println("比赛开始...");
new Thread(cdlTask,"运动员A").start();
new Thread(cdlTask,"运动员B").start();
new Thread(cdlTask,"运动员C").start();
new Thread(cdlTask,"运动员D").start();
// 等待所有线程都到达终点后再输出此语句
countDownLatch.await();
System.out.println("比赛结束...");
}
}

juc.CyclicBarrier 循环栅栏
一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)
public CyclicBarrier(int parties, Runnable barrierAction)
当多个线程同时到达临界点时,
随机挑选一个线程执行barrierAction后再同时恢复执行
计数器的值可以恢复
await
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit; class CBTask implements Runnable {
private CyclicBarrier cyclicBarrier; public CBTask(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName()+
"正在写入数据...");
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+
"写入数据完毕,等待其他线程写入完毕...");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程均已写入完毕,继续恢复执行...");
}
}
class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(4
,() -> {
System.out.println("当前线程为:"+Thread.currentThread().getName());
});
CBTask cbTask = new CBTask(cyclicBarrier);
for (int i = 0; i < 4; i++) {
new Thread(cbTask,"写线程"+(i+1)).start();
}
}
}

juc.Exchanger 线程交换器 用于两个线程直线的数据交换,当Exchanger只有一个线程时,该线程会阻塞直到有别的线程
调用exchange进入缓冲区,当前线程与新线程交换数据后同时恢复执行。
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit; class ExchangerDemo {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
Thread girlThread = new Thread(() -> {
try {
String girl = exchanger.exchange("我喜欢你.....");
System.out.println("女生说:"+girl);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
girlThread.start();
Thread boyThread = new Thread(() -> {
System.out.println("女神缓缓步入眼帘...");
try {
TimeUnit.SECONDS.sleep(1);
String boy = exchanger.exchange("我喜欢你!");
System.out.println("男生说:"+boy);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
boyThread.start();
}
}
juc.Semaphore 信号量 acquire() : 尝试占用一个信号量,失败的线程会阻塞直到有新的信号量 release() : 释放一个信号量 acquire(int n) : 尝试占用n个信号量,失败的线程会阻塞直到有新的信号量 release(int n) : 释放n个信号量
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; class SemaphoreTask implements Runnable {
private Semaphore semaphore; public SemaphoreTask(Semaphore semaphore) {
this.semaphore = semaphore;
} @Override
public void run() {
try {
semaphore.acquire(2);
System.out.println(Thread.currentThread()
.getName()+"占用2台设备生产");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread()
.getName()+"生产完毕,释放设备");
semaphore.release(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(5);
SemaphoreTask task = new SemaphoreTask(semaphore);
for (int i = 0; i < 8; i++) {
new Thread(task,"工人"+(i+1)).start();
}
}
}

这里有一篇比较好的博客关于cyclicbarrier和countdownlatch的区别:
https://blog.csdn.net/liangyihuai/article/details/83106584
juc包下四大并发工具的更多相关文章
- Java语言Lang包下常用的工具类介绍_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...
- JUC 包下工具类,它的名字叫 LockSupport !你造么?
前言 LockSupport 是 JUC 中常用的一个工具类,主要作用是挂起和唤醒线程.在阅读 JUC 源码中经常看到,所以很有必要了解一下. 公众号:liuzhihangs ,记录工作学习中的技术. ...
- JUC 常用4大并发工具类
什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: Count ...
- juc包:使用 juc 包下的显式 Lock 实现线程间通信
一.前置知识 线程间通信三要素: 多线程+判断+操作+通知+资源类. 上面的五个要素,其他三个要素就是普通的多线程程序问题,那么通信就需要线程间的互相通知,往往伴随着何时通信的判断逻辑. 在 java ...
- 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...
- JUC(三):JUC包下锁概念
线程不安全集合类 ArrayList List是线程不安全的集合类,底层是Object数组实现,初始化容量是10(其实是一个空数组,第一次扩容时,将数组扩容为10),其后每次扩容大小为当前容量的一半( ...
- java并发包下的并发工具类
1.Exchanger 功能:用于线程间数据的交换 应用场景:1)遗传算法,目前还不是特别理解 2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作 例子:是一个简单的 ...
- java多线程系列11 juc包下的队列
队列分为两类 阻塞队列 BlockingQueue提供如下两个支持阻塞的方法: (1)put(E e): 尝试把e元素放如BlockingQueue中,如果该队列的元素已满,则阻塞该线程. ...
- juc包下的集合类
import java.util.Iterator;import java.util.concurrent.CopyOnWriteArrayList; /** * 集合在多线程中同步的方式: * 1. ...
随机推荐
- Vue实战狗尾草博客管理系统第二章
伙伴们出来啦,探讨各问题,关于项目中大量的表单,大家是怎么处理的? 本章主要内容如下:底层布局,路由配置,github仓库推送关联. 关联GitHub仓库 关联建立在github已创建账号的基础上 登 ...
- 99%的程序都没有考虑的网络异常?使用Fundebug.notify()主动上报
近日看到一篇文章99%的程序都没有考虑的网络异常,开篇提到: 绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中.如果没有做 ...
- InnoDB Multi-Versioning
InnoDB 是一个数据多版本的存储引擎,它会保持它修改的数据的旧版本数据以此来支持事务特性,比如并发操作和事务的回滚.这些旧版本数据存储在一个叫做rollback segment的数据结构中(回滚段 ...
- flask uwsgi和nginx配置信息
1. 安装 pip3 install uwsgi 2. uwsgi配置信息 创建一个uwsgi.ini文件 [uwsgi] socket=/opt/script/uwsgi.sock #启动程序时所使 ...
- modbus_tk模块
modbus_tk模块 通过modbus-RTU 读取地址,调用后返回反馈数值和故障信息. modbus_tk模块安装 pip install pymodbus_tk 下面代码功能:读取地址为0x42 ...
- nginx配置多个静态资源
#user nobody; worker_processes ; worker_cpu_affinity ; #error_log logs/error.log; #error_log logs/er ...
- NLP中的预训练语言模型(二)—— Facebook的SpanBERT和RoBERTa
本篇带来Facebook的提出的两个预训练模型——SpanBERT和RoBERTa. 一,SpanBERT 论文:SpanBERT: Improving Pre-training by Represe ...
- Java中用import导入类和用Class方法加载类有什么区别?
import仅仅包含导入操作,并不包含将字节码文件加载进内存这一动作,将字节码文件加载进内存是后续的实例化操作完成的. 例如通过import导入了一堆包和类,但是后续什么都没用(没用实例化),那么导入 ...
- Revit 2019 下载链接
[安装环境]:win7/win8/win10 [64位下载] 百度网盘链接:pan.baidu.com/s/1Vq5Cnyj1G-oMNup_sXvxfQ 提取码:d6xd
- 浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳
浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳 选自arXiv,作者:Yangfan Hu等,机器之心编译. 脉冲神经网络(SNN)具有生物学上的合理性,并且其计算潜能和 ...
