Java-JUC(十):线程按序交替执行
问题:
有a、b、c三个线程,使得它们按照abc依次执行10次。
实现:
package com.dx.juc.test; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ABC {
public static void main(String[] args) {
final AlternateDemo alternateDemo=new AlternateDemo(); new Thread(new Runnable() {
public void run() {
for(int i=1;i<10;i++){
alternateDemo.loopA(i);
}
}
}, "A").start(); new Thread(new Runnable() {
public void run() {
for(int i=1;i<10;i++){
alternateDemo.loopB(i);
}
}
}, "B").start(); new Thread(new Runnable() {
public void run() {
for(int i=1;i<10;i++){
alternateDemo.loopC(i);
System.out.println("---------------------------------------");
}
}
}, "C").start();
}
} class AlternateDemo {
private Lock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition(); // 一个标号,标记当前可以执行的线程编号.1-a线程可以执行,2-b线程可以执行,3-c线程可以执行。
private int flag = 1; public void loopA(int loopNum) {
lock.lock(); try {
// 1)等待喚醒
// 如果flag标记值不是1的话,就让线程处于等待状态,直到其他线程唤醒它。
if (flag != 1) {
conditionA.await();
} // 2)被喚醒后,開始執行。
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
} // 3)修改標記flag,并喚醒下一個線程。
flag = 2;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void loopB(int loopNum) {
lock.lock(); try {
// 1)等待喚醒
// 如果flag标记值不是2的话,就让线程处于等待状态,直到其他线程唤醒它。
if (flag != 2) {
conditionB.await();
} // 2)被喚醒后,開始執行。
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
} // 3)修改標記flag,并喚醒下一個線程。
flag = 3;
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void loopC(int loopNum) {
lock.lock(); try {
// 1)等待喚醒
// 如果flag标记值不是3的话,就让线程处于等待状态,直到其他线程唤醒它。
if (flag != 3) {
conditionC.await();
} // 2)被喚醒后,開始執行。
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "-" + loopNum + "-" + i);
} // 3)修改標記flag,并喚醒下一個線程。
flag = 1;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
测试打印结果:
A-1-1
B-1-1
C-1-1
---------------------------------------
A-2-1
B-2-1
C-2-1
---------------------------------------
A-3-1
B-3-1
C-3-1
---------------------------------------
A-4-1
B-4-1
C-4-1
---------------------------------------
A-5-1
B-5-1
C-5-1
---------------------------------------
A-6-1
B-6-1
C-6-1
---------------------------------------
A-7-1
B-7-1
C-7-1
---------------------------------------
A-8-1
B-8-1
C-8-1
---------------------------------------
A-9-1
B-9-1
C-9-1
---------------------------------------
更多实现方案:
请参考《Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。》
Java-JUC(十):线程按序交替执行的更多相关文章
- JUC-Condition和Lock实践-线程按序交替执行
编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A.B.C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示.如:ABCABCABC…… 依次递归 这里只使用c ...
- java 面试题 -- 线程 按序 交替
编写一个程序,开启 3 个线程,这三个线程的 ID 分别为A.B.C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示.如:ABCABCABC…… 依次递归? packag ...
- Java并发编程(二)如何保证线程同时/交替执行
第一篇文章中,我用如何保证线程顺序执行的例子作为Java并发系列的开胃菜.本篇我们依然不会有源码分析,而是用另外两个多线程的例子来引出Java.util.concurrent中的几个并发工具的用法. ...
- 深入理解Java虚拟机(十)——线程安全与锁优化
什么是线程安全 当多个线程同时访问一个对象的时候,不需要考虑什么额外的操作就能获取正确的值,就是线程安全的. 线程安全的程度 1.不可变 不可变的对象一定是线程安全的,因为值始终只有一个. final ...
- Java两个线程实现交替运行-以交替打印奇偶数为例
本文旨在两个线程交替运行,不多哔哔直接看代码吧 public class Work2 { static final Object object = new Object(); public stati ...
- 【Java并发】线程的顺序执行
/** * 问题:有线程a.b.c,如何让它们顺序执行? * 方式一:可用Join()方法实现 * 方式二:可用newSingleThreadExecutor() * Created by Smile ...
- (三)juc高级特性——虚假唤醒 / Condition / 按序交替 / ReadWriteLock / 线程八锁
8. 生产者消费者案例-虚假唤醒 参考下面生产者消费者案例: /* * 生产者和消费者案例 */ public class TestProductorAndConsumer { public stat ...
- Java Juc学习笔记
Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...
- Java并发编程——线程安全及解决机制简介
简介: 本文主要介绍了Java多线程环境下,可能会出现的问题(线程不安全)以及相应的解决措施.通过本文,你将学习到如下几块知识: 1. 为什么需要多线程(多线程的优势) 1. 多线程带来的问题—线程安 ...
随机推荐
- 手机浏览器跳转APP
背景 对于APP来说,回流分享页是最好的最便宜的也是最病毒式的拉新方式.让新用户去下载APP是重要的.对老用户来说,可以直接调起APP也是提升用户体验和让用户有侵入式体验的重要手段.所以我们一起来看看 ...
- Handlebars.js 预编译(转)
Handlebars.js 官网上对预编译1是这样说的: 你需要安装 Node.js 你需要在全局环境中,通过 Npm 安装 handlebars 包 然后你就可以通过命令预编译你的 handleba ...
- JS本地存储信息的实现方式(localStorage 与 userData)
详细介绍请看: http://www.cnblogs.com/beiyuu/archive/2011/07/20/js-localstorage-userdata.html 里面涉及到的 demo 代 ...
- poj2115
构造出模线性方程c * x = b - a mod (2 ^ k) 很容易解. 利用LRJ书上的方法. #include <iostream> using namespace std; # ...
- Java异常(三) 《Java Puzzles》中关于异常的几个谜题
概要 本章介绍<Java Puzzles>中关于异常的几个谜题.这一章都是以代码为例,相比上一章看起来更有意思.内容包括:谜题1: 优柔寡断谜题2: 极端不可思议谜题3: 不受欢迎的宾客谜 ...
- 如何修改Oracle Enterprise Linux时区?
修改/etc/sysconfig/clock [root@psdyy-2 ~]# cat /etc/sysconfig/clock ZONE="Asia/Shanghai" UTC ...
- cocos2d-x getVisibleOrigin
getVisibleSize:表示获得视口(可视区域)的大小,如果DesignResolutionSize跟屏幕尺寸一样大,则getVisibleSize等于getWinSize.getVisible ...
- 《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了
如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...
- solc 编译Solidity
安装 sudo add-apt-repository ppa:ethereum/ethereum sudo apt-get update sudo apt-get install solc 编译 so ...
- centos7中使用yum安装tomcat以及它的启动、停止、重启
centos7中使用yum安装tomcat 介绍 Apache Tomcat是用于提供Java应用程序的Web服务器和servlet容器. Tomcat是Apache Software Foundat ...