问题:

有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(十):线程按序交替执行的更多相关文章

  1. JUC-Condition和Lock实践-线程按序交替执行

    编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A.B.C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示.如:ABCABCABC…… 依次递归 这里只使用c ...

  2. java 面试题 -- 线程 按序 交替

    编写一个程序,开启 3 个线程,这三个线程的 ID 分别为A.B.C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示.如:ABCABCABC…… 依次递归? packag ...

  3. Java并发编程(二)如何保证线程同时/交替执行

    第一篇文章中,我用如何保证线程顺序执行的例子作为Java并发系列的开胃菜.本篇我们依然不会有源码分析,而是用另外两个多线程的例子来引出Java.util.concurrent中的几个并发工具的用法. ...

  4. 深入理解Java虚拟机(十)——线程安全与锁优化

    什么是线程安全 当多个线程同时访问一个对象的时候,不需要考虑什么额外的操作就能获取正确的值,就是线程安全的. 线程安全的程度 1.不可变 不可变的对象一定是线程安全的,因为值始终只有一个. final ...

  5. Java两个线程实现交替运行-以交替打印奇偶数为例

    本文旨在两个线程交替运行,不多哔哔直接看代码吧 public class Work2 { static final Object object = new Object(); public stati ...

  6. 【Java并发】线程的顺序执行

    /** * 问题:有线程a.b.c,如何让它们顺序执行? * 方式一:可用Join()方法实现 * 方式二:可用newSingleThreadExecutor() * Created by Smile ...

  7. (三)juc高级特性——虚假唤醒 / Condition / 按序交替 / ReadWriteLock / 线程八锁

    8. 生产者消费者案例-虚假唤醒 参考下面生产者消费者案例: /* * 生产者和消费者案例 */ public class TestProductorAndConsumer { public stat ...

  8. Java Juc学习笔记

    Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...

  9. Java并发编程——线程安全及解决机制简介

    简介: 本文主要介绍了Java多线程环境下,可能会出现的问题(线程不安全)以及相应的解决措施.通过本文,你将学习到如下几块知识: 1. 为什么需要多线程(多线程的优势) 1. 多线程带来的问题—线程安 ...

随机推荐

  1. SLAM(一)----学习资料整理

    转自:http://www.cnblogs.com/wenhust/ 书籍: 1.必读经典 Thrun S, Burgard W, Fox D. <Probabilistic robotics& ...

  2. CentOS下KVM配置NAT网络(网络地址转换模式)

    KVM虚拟机Nat方式上网: # 查看当前活跃的网络 virsh net-list # 查看该网络的详细配置 virsh net-dumpxml default 客户机的XML配置文件中interfa ...

  3. 使用WindowsAPICodePack实现翻译功能

    仅限于以下几种语言间的翻译: 在我的另一篇博文<图片批量压缩>中,有介绍WindowsAPICodePack库,该库是微软提供的一套基于Win7及以上版本操作系统的系统库,可以帮助我们完成 ...

  4. HDU 4733 G(x) (2013成都网络赛,递推)

    G(x) Time Limit: 2000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  5. javaDoc 注释规范

    Javadoc虽然是Sun公司为Java文档自动生成设计的,可以从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档.但是Javadoc的注释也符合C的注释格式,而且doxyen ...

  6. Java 中 byte、byte 数组和 int、long 之间的转换

    Java 中 byte 和 int 之间的转换源码: //byte 与 int 的相互转换 public static byte intToByte(int x) { return (byte) x; ...

  7. JavaScript学习总结(十五)——Function类

    在JavaScript中,函数其实是对象,每个函数都是Function类的实例,既然函数对象,那么就具有自己的属性和方法,因此,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. 一.函数的 ...

  8. Download Hacking Team Database from torrent using magnet link

    20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送) 国内私募机构九鼎控股打造,九鼎投资是在全国股 ...

  9. iOS 7.1 系统可以设置 button shapes,此功能可让按钮多一条下滑线

    IniOS 7, Apple completely revamped the user interface to give it a fresh and modern look. One of the ...

  10. 解决eclipse中web项目出现Project facet Java version 1.8 is not supported.的问题

    项目的jdk和tomcat的jdk版本不同,将eclipse-preference-server-runtime environments点击你要用的tomcat点击edit-jre选择和你项目对应的 ...