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. ...
随机推荐
- python 的三元操作符
条件表达式(三元操作符) 1.有了这个三元操作符的条件表达式,你可以使用一条语句来完成下面的条件判断和赋值操作: x,y=4,5 if x<y: temp = x else: temp = ...
- win10无法在桌面右键快捷打开个性化设置、显示设置,在任务栏右键无法快捷打开任务栏设置
Win+R,输入regedit,定位到HKEY_CURRENT_USER\Software\Classes\ 找到列表中的ms-settings 将其删除即可解决! 转自百度知道
- 69.x的平方根 (平)(简单)
实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4输出: 2示例 2: ...
- 【视频技术】ffmpeg截取图片(Mac)
1. 输出单张图片:ffmpeg -i NLP-CNN.mp4 -f image2 -ss 2000 -vframes 1 -s 220*220 NLP-CNN-003.jpg 2. 输出所有图片: ...
- 修改woocommerce列表产品显示数量
WooCommerce列表产品数量默认显示为10,如果是显示3列或4列,则最后一行会有空白留出,为了美观,往往我们要设置显示合适的产品数量.因此,只要把如下代码复制到当前主题的functions.ph ...
- redhat 网卡绑定
一.bonding技术 bonding(绑定)是一种linux系统下的网卡绑定技术,可以把服务器上n个物理网卡在系统内部抽象(绑定)成一个逻辑上的网卡,能够提升网络吞吐量.实现网络冗余.负载等功能,有 ...
- 【作用域】词法作用域(静态作用域,如:js)、动态作用域(如:.bash脚本)
作用域 作用域是指程序源代码中定义变量的区域. 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript 采用词法作用域(lexical scoping),也就是静态作 ...
- 微信小程序 - 支付(后端代码实现)
小程序支付 业务流程时序图 官方文档 步骤: 1. Openid 在小程序初次加载的时候就已经获取(详情见 小程序登录) 2. 生成商户订单 1.商品信息由小程序端提供 2.提供支付统一下单接口所需参 ...
- windows上传文件到 linux的hdfs
一.windows上传文件到 linux的hdfs 1.先在 centos 上开启 hdfs, 用 jps 可以看到下面信息, 说明完成开启 2.在win上配置 hadoop (https://www ...
- B1038 统计同成绩学生 (20 分)
#include<iostream> #include<cstring> using namespace std; const int maxn = 10010; int sc ...