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包下四大并发工具的更多相关文章

  1. Java语言Lang包下常用的工具类介绍_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...

  2. JUC 包下工具类,它的名字叫 LockSupport !你造么?

    前言 LockSupport 是 JUC 中常用的一个工具类,主要作用是挂起和唤醒线程.在阅读 JUC 源码中经常看到,所以很有必要了解一下. 公众号:liuzhihangs ,记录工作学习中的技术. ...

  3. JUC 常用4大并发工具类

    什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: Count ...

  4. juc包:使用 juc 包下的显式 Lock 实现线程间通信

    一.前置知识 线程间通信三要素: 多线程+判断+操作+通知+资源类. 上面的五个要素,其他三个要素就是普通的多线程程序问题,那么通信就需要线程间的互相通知,往往伴随着何时通信的判断逻辑. 在 java ...

  5. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  6. JUC(三):JUC包下锁概念

    线程不安全集合类 ArrayList List是线程不安全的集合类,底层是Object数组实现,初始化容量是10(其实是一个空数组,第一次扩容时,将数组扩容为10),其后每次扩容大小为当前容量的一半( ...

  7. java并发包下的并发工具类

    1.Exchanger 功能:用于线程间数据的交换 应用场景:1)遗传算法,目前还不是特别理解  2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作 例子:是一个简单的 ...

  8. java多线程系列11 juc包下的队列

    队列分为两类  阻塞队列 BlockingQueue提供如下两个支持阻塞的方法:   (1)put(E e): 尝试把e元素放如BlockingQueue中,如果该队列的元素已满,则阻塞该线程.   ...

  9. juc包下的集合类

    import java.util.Iterator;import java.util.concurrent.CopyOnWriteArrayList; /** * 集合在多线程中同步的方式: * 1. ...

随机推荐

  1. Vue实战狗尾草博客管理系统第二章

    伙伴们出来啦,探讨各问题,关于项目中大量的表单,大家是怎么处理的? 本章主要内容如下:底层布局,路由配置,github仓库推送关联. 关联GitHub仓库 关联建立在github已创建账号的基础上 登 ...

  2. 99%的程序都没有考虑的网络异常?使用Fundebug.notify()主动上报

    近日看到一篇文章99%的程序都没有考虑的网络异常,开篇提到: 绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中.如果没有做 ...

  3. InnoDB Multi-Versioning

    InnoDB 是一个数据多版本的存储引擎,它会保持它修改的数据的旧版本数据以此来支持事务特性,比如并发操作和事务的回滚.这些旧版本数据存储在一个叫做rollback segment的数据结构中(回滚段 ...

  4. flask uwsgi和nginx配置信息

    1. 安装 pip3 install uwsgi 2. uwsgi配置信息 创建一个uwsgi.ini文件 [uwsgi] socket=/opt/script/uwsgi.sock #启动程序时所使 ...

  5. modbus_tk模块

    modbus_tk模块 通过modbus-RTU 读取地址,调用后返回反馈数值和故障信息. modbus_tk模块安装 pip install pymodbus_tk 下面代码功能:读取地址为0x42 ...

  6. nginx配置多个静态资源

    #user nobody; worker_processes ; worker_cpu_affinity ; #error_log logs/error.log; #error_log logs/er ...

  7. NLP中的预训练语言模型(二)—— Facebook的SpanBERT和RoBERTa

    本篇带来Facebook的提出的两个预训练模型——SpanBERT和RoBERTa. 一,SpanBERT 论文:SpanBERT: Improving Pre-training by Represe ...

  8. Java中用import导入类和用Class方法加载类有什么区别?

    import仅仅包含导入操作,并不包含将字节码文件加载进内存这一动作,将字节码文件加载进内存是后续的实例化操作完成的. 例如通过import导入了一堆包和类,但是后续什么都没用(没用实例化),那么导入 ...

  9. Revit 2019 下载链接

    [安装环境]:win7/win8/win10 [64位下载] 百度网盘链接:pan.baidu.com/s/1Vq5Cnyj1G-oMNup_sXvxfQ  提取码:d6xd

  10. 浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳

    浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳 选自arXiv,作者:Yangfan Hu等,机器之心编译. 脉冲神经网络(SNN)具有生物学上的合理性,并且其计算潜能和 ...