package com.wf.zhang.juc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /*
* 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,
* 要求输出的结果必须按顺序显示。
* 如:ABCABCABC…… 依次递归
*/
public class TestABCAlternate { public static void main(String[] args) {
AlternateDemo ad = new AlternateDemo(); new Thread(new Runnable() {
@Override
public void run() { for (int i = 1; i <= 20; i++) {
ad.loopA(i);
} }
}, "A").start(); new Thread(new Runnable() {
@Override
public void run() { for (int i = 1; i <= 20; i++) {
ad.loopB(i);
} }
}, "B").start(); new Thread(new Runnable() {
@Override
public void run() { for (int i = 1; i <= 20; i++) {
ad.loopC(i); System.out.println("-----------------------------------");
} }
}, "C").start();
} } class AlternateDemo{ private int number = 1; //当前正在执行线程的标记 private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition(); /**
* @param totalLoop : 循环第几轮
*/
public void loopA(int totalLoop){
lock.lock(); try {
//1. 判断
if(number != 1){
condition1.await();
} //2. 打印
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
} //3. 唤醒
number = 2;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void loopB(int totalLoop){
lock.lock(); try {
//1. 判断
if(number != 2){
condition2.await();
} //2. 打印
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
} //3. 唤醒
number = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public void loopC(int totalLoop){
lock.lock(); try {
//1. 判断
if(number != 3){
condition3.await();
} //2. 打印
for (int i = 1; i <= 1; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
} //3. 唤醒
number = 1;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} }

 ....            ...

JUC-9-线程按序交替的更多相关文章

  1. Java-JUC(十):线程按序交替执行

    问题: 有a.b.c三个线程,使得它们按照abc依次执行10次. 实现: package com.dx.juc.test; import java.util.concurrent.locks.Cond ...

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

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

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

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

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

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

  5. 一个线程加一运算,一个线程做减一运算,多个线程同时交替运行--synchronized

    使用synchronized package com.pb.thread.demo5; /**使用synchronized * 一个线程加一运算,一个线程做减法运算,多个线程同时交替运行 * * @a ...

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

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

  7. 细说JUC的线程池架构

    前言 线程的创建是需要JVM和OS(操作系统)相互配合的,一次的创建要花费许多的资源. 1.首先,JVM要为该线程分配堆栈和初始化大量内存块,栈内存至少是1MB. 2.其次便是要进行系统的调用,在OS ...

  8. JUC自定义线程池练习

    JUC自定义线程池练习 首先上面该线程池的大致流程 自定义阻塞队列 首先定义一个双向的队列和锁一定两个等待的condition 本类用lock来控制多线程下的流程执行 take和push方法就是死等, ...

  9. JUC——ThreadFactory线程工厂类(四)

    ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...

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

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

随机推荐

  1. How to: Display a List of Non-Persistent Objects in a Popup Dialog 如何:在弹出对话框中显示非持久化对象列表

    This example demonstrates how to populate and display a list of objects that are not bound to the da ...

  2. 一些实用的Django+HTML设置

    一.关于引入变量 1.变量引入方法: {% block 块名称 %} <p>{{变量名}}<p> {% endblock %} 2.引入变量的值中标签是否转义: 不转义: {% ...

  3. ElementUi中el-table分页效果

    现实的场景中很经常遇到表格el-table数据过多,为了更好的用户体验,所以我们需要用到分页,一般分页可以视数据量的大小可分为前端控制和后端控制. 先看下效果(已做脱敏处理) 图1 前端el-tabl ...

  4. Spring Boot与ActiveMQ整合

    Spring Boot与ActiveMQ整合 1使用内嵌服务 (1)在pom.xml中引入ActiveMQ起步依赖 <dependency> <groupId>org.spri ...

  5. C编程小结1

    1. ‘\0’表示字符串结束符 2. 变量之间互相赋值一定要考虑他们的数据类型,要强制转换匹配上了或者进行一些处理才能赋值,同时读程序的时候也要注意这一点,否则可能看不懂.如: sData[0]=wD ...

  6. Python升级后ssl模块不可用问题解决和浅析

    在Cent0S 7.5下将Python 2.7.5升级到Python 3.6.6后,发现ssl模块不可用,具体详细信息如下所示: [root@db-server ~]# pip list Packag ...

  7. Linux系统学习 二十、SAMBA服务—介绍、安装、端口

    1.简介 网络数据文件共享服务器 可以和Windows中的网上邻居通用 数据共享的方法: Windows中最常用的是“网上邻居”.网上邻居使用的文件系统是CIFS(通用互联网文件系统)协议进行数据共享 ...

  8. 苹果 macOS 安装 Source Code Pro

    1. 下载     到 Source Code Pro 的 GitHub 官网下载:https://github.com/adobe-fonts/source-code-pro 点击 GitHub 中 ...

  9. 菜鸟刷面试题(三、Redis篇)

    目录: redis是什么?都有哪些使用场景? redis有哪些功能? redis和memecache有什么区别? redis为什么是单线程的? 什么是缓存穿透?怎么解决? redis支持的数据类型有哪 ...

  10. Linux中fuser命令用法详解

    描述: fuser可以显示出当前哪个程序在使用磁盘上的某个文件.挂载点.甚至网络端口,并给出程序进程的详细信息. fuser显示使用指定文件或者文件系统的进程ID. 默认情况下每个文件名后面跟一个字母 ...