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)创建包 ...
随机推荐
- webpack练手项目之easySlide(一):初探webpack
最近在学习webpack,正好拿了之前做的一个小组件,图片轮播来做了下练手,让我们一起来初步感受下webpack的神奇魅力. webpack是一个前端的打包管理工具,大家可以前往:http:/ ...
- Jenkins使用过程中注意事项
jenkins自动部署注意事项: 安装jenkins https://blog.csdn.net/qq_37372007/article/details/81586751 1.当提示错误ERROR: ...
- Trunk 实现跨交换机 VLAN 通信
当网络中有多台交换机时,位于不同交换机上的相同VLAN的主机之间时如何通信的呢?我们使用Trunk实现跨交换机VLAN通信.还有以太网通道的操作哦. 实验拓扑 两台交换机直连,每台下面再连接两台VPC ...
- 计算机网络基础之IP地址详解
计算机网络基础之IP地址详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.IP地址概述 1>.什么是IP地址 我们为什么要使用逻辑地址(IP地址)来标识网络设备,而不采 ...
- LeetCode初级算法--其他01:位1的个数
LeetCode初级算法--其他01:位1的个数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'的解决方法:
全文转载至:http://www.cnblogs.com/testyao/p/5658200.html python3中用HTMLTestRunner.py报ImportError: No modul ...
- 10、Python迭代器与生成器(iterator、for循环、generator、yield)
一.迭代器(foreach) 1.可迭代的对象 内置有__iter__方法的都叫可迭代的对象. Python内置str.list.tuple.dict.set.file都是可迭代对象. x = 1._ ...
- npm run build打包时修改的路径
- 趣味编程:FizzBuzz(Haskell版)
g :: Int -> Int -> Int -> String g n 0 0 = "FizzBuzz" g n 0 _ = "Fizz" ...
- AndroidStudio中Flutter打包APK
1.生成签名文件 在打包之前我们需要一个签名文件,证明文件的唯一性. keytool -genkey -v -keystore F:\APP\sign.jks -keyalg RSA -keysize ...