利用Condition实现多线程交替执行
一、需求
- A、B、C 三个线程,循环10次,打印出自己的名称,ABC,ABC,ABC...
- A、B、C 三个线程,循环10次,打印出自己的名称,A一次,B三次,C五次,ABBBCCCCC,ABBBCCCCC
1.1、循环打印ABC
package com.example.demo.juc; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @author DUCHONG
* @since 2019-01-21 10:46
**/
public class ABC { public static void main(String[] args) { PrintDemo pd=new PrintDemo();
//A 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printA(i);
}
}
},"A").start(); //B 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printB(i);
}
}
},"B").start(); //C 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printC(i);
}
}
},"C").start();
}
} class PrintDemo{ Lock lock =new ReentrantLock(); private Condition conditionA=lock.newCondition();
private Condition conditionB=lock.newCondition();
private Condition conditionC=lock.newCondition(); //哪个线程等待与否的标记,flag的值:
// 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
// 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
// 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A 外层一次循环结束。
private Integer flag=1;
//打印A
public void printA(int loop){
try{
lock.lock();
if(flag!=1){
conditionA.await();
} for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=2;
conditionB.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} }
//打印B
public void printB(int loop){
try{
lock.lock();
if(flag!=2){
conditionB.await();
} for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
} flag=3;
conditionC.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} }
//打印C
public void printC(int loop){
try{
lock.lock();
if(flag!=3){
conditionC.await();
} for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=1;
conditionA.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} } }
结果:

1.2、循环打印ABBBCCCC
package com.example.demo.juc; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @author DUCHONG
* @since 2019-01-21 14:15
**/
public class ABBB { public static void main(String[] args) {
PrintABBBDemo pd=new PrintABBBDemo();
//A 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printA(i);
}
}
},"A").start(); //B 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printB(i);
}
}
},"B").start(); //C 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printC(i);
}
}
},"C").start();
} } class PrintABBBDemo{ Lock lock =new ReentrantLock(); private Condition conditionA=lock.newCondition();
private Condition conditionB=lock.newCondition();
private Condition conditionC=lock.newCondition(); //哪个线程等待与否的标记,flag的值:
// 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
// 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
// 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A 外层一次循环结束。
private Integer flag=1;
//打印A
public void printA(int loop){
try{
lock.lock();
if(flag!=1){
conditionA.await();
} for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=2;
conditionB.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} }
//打印B
public void printB(int loop){
try{
lock.lock();
if(flag!=2){
conditionB.await();
} for (int i=1;i<=3;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
} flag=3;
conditionC.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} }
//打印C
public void printC(int loop){
try{
lock.lock();
if(flag!=3){
conditionC.await();
} for (int i=1;i<=5;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=1;
conditionA.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
} } }
结果:

利用Condition实现多线程交替执行的更多相关文章
- Java并发编程(二)如何保证线程同时/交替执行
第一篇文章中,我用如何保证线程顺序执行的例子作为Java并发系列的开胃菜.本篇我们依然不会有源码分析,而是用另外两个多线程的例子来引出Java.util.concurrent中的几个并发工具的用法. ...
- php利用wsh突破函数禁用执行命令(安全模式同理)
php利用wsh突破函数禁用执行命令(安全模式同理) 前提.需要服务器支持wsh.并知道php安装目录 但是php利用wsh执行命令是没有asp的权限高的. 突破代码 <?php $cmd= ...
- ASP.NET 多线程 监控任务执行情况,并显示进度条
关于多线程的基本概念和知识在本文中不多讲,而且我懂的也不是很透,说的太多误人子弟...对于我来说,做本文提到的功能够用就行,等实现其他效果不够用的时候,再深入研究 推荐看园子里的两篇博客应该就有个基本 ...
- 多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture
目录 1.Futrue 2.FutureTask 3.CompletionService 4.CompletableFuture 5.总结 ================正文分割线========= ...
- new Random().Next(1, 100); 多线程同时执行结果很高概率相同,
/// <summary> /// new Random().Next(1, 100); 多线程同时执行结果很高概率相同, /// 是用的当前时间为seed,时间相同结果相同 /// // ...
- PHP利用CURL_MULTI实现多线程
PHP中的curl_multi一类函数可以实现同时请求多个url,而不是一个一个依次请求,这就类似一个进程实现了多个线程的功能,因此可以使用PHP利用CURL_MULTI实现完成多线程类的任务,下面就 ...
- C# 不使用Task实现的多线程顺序执行
多线程有很好的并发性即无序性,在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项 ...
- Condition实现多线程顺序打印
Condition实现多线程顺序打印: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.R ...
- 利用osql/ocmd批处理批量执行sql文件
原文:利用osql/ocmd批处理批量执行sql文件 上周在测试环境建了几十张表,保存了.sql文件,准备在正式环境重建的时候懒得一个个打开建了,做一在网上搜寻了一下,果然有简单点的方法. 利用osq ...
随机推荐
- PHP---文件上传与下载
转自http://www.cnblogs.com/lazycat-cz/p/4113037.html 安全性能---水平不够 ╮(╯_╰)╭ 文件上传--->就是将本地的文件上传到服务器上.(H ...
- LOJ2359. 「NOIP2016」天天爱跑步【树上差分】
LINK 思路 首先发现如果对于一个节点,假设一个节点需要统计从字数内来的贡献 需要满足\(dep_u - dep_s = w_u\) 这个条件其实可以转化成\(dep_u - w_u = dep_s ...
- JavaScript年月日和时间戳互转
/** 一丶将日期单位转为时间戳 / 毫秒 **/ var str="2017年06月2日" var time = str.replace(/年/i,"-"). ...
- c#开发的程序安装时动态指定windows服务名称
转自:http://www.jb51.net/article/30549.htm 前段时间由于项目的需求,要在Windows里把同样的组件制作成多个不同名称的服务,这些服务完成类似的功能,仅需要修改业 ...
- keil 赋值之后再声明变量提示错误error: #268: declaration may not appear after executable statement in block
勾选 C99 Mode 即可 假如没有C99 Mode的选项,那么我们可以用大括号将代码括起来,这样编译也不会报错 if( (! bMemAddrAllowAccess(checkAddr) )) { ...
- table样式的下拉框(angularjs)
前言 虽然使用的技术比较老了,但是思想却还是适用于现在的vue等框架. 一:实现的样式 二:实现包括的功能点 1:下拉框内容是表格,类似于一个弹窗 表格内容最多六行,超出的显示滚动条,表头固定,可滚动 ...
- c# 启动关闭sql服务
static void Main(string[] args) { ServiceController sc = new ServiceController("MSSQL$SQLEXPRES ...
- 18.9.10 LeetCode刷题笔记
本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...
- pandas之DateFrame
float_df = pd.DataFrame((0.45*np.arange(1,9)).reshape(4,2), index=[1,2,3,4], columns=['col_one', 'co ...
- cassandra的一些概念
分区器Partitioners 在集群内,根据设置的副本数,决定数据如何分发,允许跨机房 具体看 http://teddymaef.github.io/learncassandra/cn/replic ...