问题:

有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. spring-boot 速成(3) actuator

    actuator 通过暴露一系列的endpoints可以让开发者快速了解spring boot的各项运行指标,比如:线程数,jvm剩余内存等一系列参数. 启用方法很简单,参考下面: dependenc ...

  2. HDU 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)

    Walk Through Squares Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  3. HDU 4731 Minimum palindrome (2013成都网络赛,找规律构造)

    Minimum palindrome Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  4. Unity3D对安卓盒子的支持

    一般的安卓盒子主要按键包含 1.方向键:上下左右 2.确认 3.返回 4.音量(Unity无法获取),须要在安卓层将事件发上来,KeyCode = 24,25 基本的函数是 if (Input.Get ...

  5. A CANBus Tiny Network without Transceiver ICs : STM32F4 Discovery

    Sometimes you have a CAN equipped processor on a low cost board but it has no CAN transceiver chips. ...

  6. python dtrace 安装与应用

    https://ipfans.github.io/2016/09/tracing-python-program-with-dtrace/?utm_source=tuicool&utm_medi ...

  7. lufylegend:动画

    1.动画1 <script type="text/javascript"> var loader,anime,layer; //初始化画布 init(200, &quo ...

  8. future封装了callable,thread封装future。

    三.使用Callable,Future返回结果 总结:future封装了callable,thread封装future.将callable的返回结果封装在future中,thread封装future, ...

  9. Objective-C内存布局

    在我的理解来说: 对象(object)即一块内存,本文要探讨的是一个Objective-C对象在内存的布局(layout)问题,水果的官方文档有说,一个类(class)如果不需要从NSObject继承 ...

  10. 分享一段ios数据库代码,包括对表的创建、升级、增删查改

    分享一段ios数据库代码.包括创建.升级.增删查改. 里面的那些类不必细究,主要是数据库的代码100%可用. 数据库升级部分,使用switch,没有break,低版本一次向高版本修改. // DB.h ...