Java-JUC(十二):有3个线程。线程A和线程B并行执行,线程C需要A和B执行完成后才能执行。可以怎么实现?
方案(一)CountDownLatch:
使用CountDownLatch+Semaphore方式实现:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore; public class TestABC {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(2);
Semaphore semaphoreC = new Semaphore(1); Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(newjava.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
countDownLatch.countDown();
}
}, "Thread-A"); Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(newjava.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
countDownLatch.countDown();
}
}, "Thread-B"); Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
try {
semaphoreC.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
semaphoreC.release();
}
}, "Thread-C"); // 占用C锁,直到A/B线程完成后,才释放C锁。
semaphoreC.acquire(); threadA.start();
threadB.start();
threadC.start(); countDownLatch.await();
// 释放C锁,让C线程有获取锁的可能
semaphoreC.release(); }
}
上边使用CountDownLatch+Semaphore方式实现,但是缺点:上边这种方式会导致线程阻塞情况。下边这种方案是可以实现不阻塞线程的用法:
import java.util.concurrent.CountDownLatch;
public class TestABC {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(2);
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new java.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
countDownLatch.countDown();
}
}, "Thread-A");
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new java.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
countDownLatch.countDown();
}
}, "Thread-B");
Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
// 在C中等待A/B運算結束
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException("CountDownLatch等待失败。。。",e);
}
System.out.println(Thread.currentThread().getName());
}
}, "Thread-C");
threadA.start();
threadB.start();
threadC.start();
}
}
方案(二):CyclicBarrier
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; public class TestABC {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier=new CyclicBarrier(3); Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new java.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()); // 冲破栅栏代表A线程结束
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
throw new RuntimeException("cylicBarrier.await()拋出異常:",e);
}
}
}, "Thread-A"); Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new java.util.Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()); // 冲破栅栏代表B线程结束
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
throw new RuntimeException("cylicBarrier.await()拋出異常:",e);
}
}
}, "Thread-B"); Thread threadC = new Thread(new Runnable() {
@Override
public void run() {
// 等待前两个(A/B)线程结束,只有前两个(A/B)线程结束了才能满足3个线程都冲破栅栏,
try {
// 等待栅栏被冲破,冲破栅栏的条件是:A/B/C三个线程都到达await()。
// 只有栅栏冲破,才能向下执行,否则先到达的线程等待。
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
throw new RuntimeException("cylicBarrier.await()拋出異常:",e);
}
// 满足了三个线程都冲破栅栏才向下执行
System.out.println(Thread.currentThread().getName());
}
}, "Thread-C"); threadA.start();
threadB.start();
threadC.start();
}
}
Java-JUC(十二):有3个线程。线程A和线程B并行执行,线程C需要A和B执行完成后才能执行。可以怎么实现?的更多相关文章
- Java基础十二--多态是成员的特点
Java基础十二--多态是成员的特点 一.特点 1,成员变量. 编译和运行都参考等号的左边. 覆盖只发生在函数上,和变量没关系. Fu f = new Zi();System.out.println( ...
- “全栈2019”Java第九十二章:外部类与内部类成员覆盖详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第十二章:变量
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第二十二章:控制流程语句中的决策语句if-else
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- JAVA提高十二:HashMap深入分析
首先想说的是关于HashMap源码的分析园子里面应该有很多,并且都是分析得很不错的文章,但是我还是想写出自己的学习总结,以便加深自己的理解,因此就有了此文,另外因为小孩过来了,因此更新速度可能放缓了, ...
- Java主线程在子线程执行完毕后再执行
一.join() Thread中的join()方法就是同步,它使得线程之间由并行执行变为串行执行. public class MyJoinTest { public static void main( ...
- C# 本进程执行完毕后再执行下一线程
最近做了一套MES集成系统,由上料到成品使自动化运行,其中生产过程是逐步的,但是每一个动作都需要独立的线程进行数据监听,那么就需要实现线程等待. 代码: using System; using Sys ...
- java——第十二章 异常处理和文本I/O
1.异常处理: 使用try_throw_catch块模块 优点:将检测错误(由被调用的方法完成)从处理错误(由调用方法完成)中分离出来. 例子: package test; import java.u ...
- Java系列学习(十二)-开始Eclipse
1.用Eclipse来写一个HelloWorld (1)选择工作空间 工作空间其实就是我们写的源代码所在的目录 (2)创建一个Java项目 [File-New-Java Project] (3)创建包 ...
随机推荐
- ABAP-System Functions
ABAP_CALLSTACK ABAP_CRC64 ABAP_PRECOMPILED_HEADER_USAGE ABSTOR_TEST AB_CALL_LITL_CHECK AB_CALL_STACK ...
- 如何在SAP gateway系统配置路由到后台系统的OData服务路径
看这张架构图,SAP Gateway系统也叫frontend系统,通过RFC远程调用SAP后台系统的OData服务实现. 以SAP CRM Fiori应用My Opportunity为例,使用事务码/ ...
- centos7 上Docker安装与启动
1. docker centos 文档地址 https://docs.docker.com/install/linux/docker-ce/centos/ 2. 安装环境说明: docker社区版 ...
- echarts 曲线平滑配置
来源:https://blog.csdn.net/sinat_36422236/article/details/62430114 series : [ { name:'your name', symb ...
- VMware15.5版本通过挂载系统光盘搭建yum仓库
VMware15.5版本通过挂载系统光盘搭建yum仓库一.1.打开CentOS 7虚拟机. 2.登录虚拟机,选择未列出 用户名:root 密码:输入自己设置的密码 点击登录. 3.右键单击打开终端. ...
- DB开发规范---初稿
1 公共约定 1.1 存储引擎 默认统一使用InnoDB引擎 1.2 字符集设定 后续新建DB默认使用utf8mb4字符集,校对规则使用utf8mb4_general_bin. 历史DB多使用utf8 ...
- 你真的理解CountDownLatch与CyclicBarrier使用场景吗?
原文:https://blog.csdn.net/zzg1229059735/article/details/61191679 相信每个想深入了解多线程开发的Java开发者都会遇到CountDownL ...
- Pollard-rho的质因数分解
思路:见参考文章(原理我是写不粗来了) 代码: 用到了快速幂,米勒罗宾素性检验. #include <iostream> #include <time.h> #include ...
- 使用Visual studio查看exe或DLL文件的依赖项
事先准备:只要 Visual Studio 任何版本即可. 点击开始 -> 程序 -> Visual Studio对应的版本,打开Visual Studio Tools -> 选择 ...
- 【CLAA系列】CLAA协议学习(CS方向)
工作上用Lora,需要开发相关模块,分享一下学习的内容: Lora: 博主是做IT的,对Lora不了解.简单理解为LPWAN(Low Power Wide Area Network)中一种技术,目前主 ...