利用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 ...
随机推荐
- css---选择器的特殊性
特殊性这点吃了亏,是该梳理一下了~ 先说一下大概的选择器,沾代码 最权威的还是<css权威指南> 我们把特殊性分为4个等级,每个等级代表一类选择器,每个等级的值为其所代表的选择器的个数乘以 ...
- tensorflow图像基本处理
tensorflow库提供的专门的图片处理库,以下只是部分示例,更多函数请参照源码'\tensorflow_api\v1\image__init__.py' 加载图像 方式1: 使用tf.gfile. ...
- CF1083A The Fair Nut and the Best Path
CF1083A The Fair Nut and the Best Path 先把边权搞成点权(其实也可以不用),那么就是询问树上路径的最大权值. 任意时刻权值非负的限制可以不用管,因为若走路径 \( ...
- bzoj 4303 数列
bzoj 4303 数列 二维 \(KD-Tree\) 模板题. \(KD-Tree\) 虽然在更新和查询的方式上类似于线段树,但其本身定义是类似于用 \(splay/fhq\ treap\) 维护区 ...
- JSONModel源码阅读笔记
JSONModel是一个解析服务器返回的Json数据的库. http://blog.csdn.net/dyllove98/article/details/9050905 通常服务器传回的json数据要 ...
- python(十三):网络编程之socket与socketserver
socket是操作系统中I/O系统延伸部分,支持TCP和UDP等网络通信协议,它使计算机之间(或其本身)的进程通信称为可能.socket中的socket()函数.recv()函数和send()函数,相 ...
- Python Tkinter 学习历程 一
一丶一个简单的程序 from tkinter import * #引入所有类#查看tk版本#tkinter._test() root = Tk(); #对这个类进行实例化 w1 = Label(roo ...
- Linux环境下安装Nexus
JDK的安装本文不在说了. 直接进入正题. 1. wget http://www.sonatype.org/downloads/nexus-2.13.0-01-bundle.tar.gz 获取nexu ...
- C++中const使用注意要点(二)
当const修饰类的成员变量 1.const修饰类的非静态成员时必须在构造函数初始化列表上初始化: 在构造函数内会提示表达式必须是可修改的左值,因为在构造函数内并不是初始化,仅仅是赋值,而const类 ...
- 2016-the brave never die
2016年最后一天工作日了,由于这段时间一直忙于春节项目没时间写点关于2016年的总结,回忆一下,2016年其实还有很多事情没做好,究其原因,感觉是因为对于2016年没有做任何的规划和计划,就凭着一股 ...