博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程实现有序输出ABC
阅读量:4198 次
发布时间:2019-05-26

本文共 4976 字,大约阅读时间需要 16 分钟。

3个线程,线程1输出A,线程2输出B,线程3输出C,让这个3个线程循环有序地输出ABCABC…

看到这个题目,感觉很有意思,问题的本质是在多线程执行环境,控制线程的执行顺序,实现的方式有非常多种,本质上需要解决Java多线程环境下的线程执行的同步和利用锁机制来控制线程的执行顺序。

方式1:利用synchronized

这种方式也就是使用java内置的monitor机制,配合wait和notifyAll,代码如下:

(1)利用volatile做线程间资源的同步访问,同时作为线程调度的标志;

(2)利用notifyAll来唤醒其他等待当前的monitor资源的线程;

public class ThreadOrderWithSync {    private volatile int flag = 'A';    private final static Object LOCK = new Object();    Runnable a = () -> {        while (true) {            synchronized (LOCK) {                if (flag == 'A' ) {                    System.out.println("A");                    flag = 'B';                    // let other thread race to get the monitor                    LOCK.notifyAll();                } else {                    try {                        LOCK.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    };    Runnable b = () -> {        while (true) {            synchronized (LOCK) {                if (flag == 'B' ) {                    System.out.println("B");                    flag = 'C';                    // let other thread race to get the monitor                    LOCK.notifyAll();                } else {                    try {                        LOCK.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    };    Runnable c = () -> {        while (true) {            synchronized (LOCK) {                if (flag == 'C' ) {                    System.out.println("C");                    flag = 'A';                    // let other thread race to get the monitor                    LOCK.notifyAll();                } else {                    try {                        LOCK.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    };    public void runTest() {        Thread ta = new Thread(a);        Thread tb = new Thread(b);        Thread tc = new Thread(c);        ta.start();        tb.start();        tc.start();    }    public static void main(String[] args) {        ThreadOrderWithSync sync = new ThreadOrderWithSync();        sync.runTest();    }}

方式2:利用并发包ReentrantLock和Condition的锁机制

上面方式1的synchronized机制,因为当前的所有线程都争用同一个monitor资源,因此只能通过notifyAll来通知其他线程来加锁,因此每次都会出现race condition,但是,通过ReentrantLock的Condition,我们可以精确控制,下一个该唤醒signal的线程是哪一个(因为我们知道执行的顺序是A->B->C的循环),相比synchronized的机制,Condition机制可以更精细化线程的调度设计,代码示例如下:

/** * @author xijin.zeng created on 2018/8/31 * Thrads runing order: A->B->C */public class ThreadOrderWithCondition {
private static final ReentrantLock LOCK = new ReentrantLock(); private static final Condition C_A = LOCK.newCondition(); private static final Condition C_B = LOCK.newCondition(); private static final Condition C_C = LOCK.newCondition(); /** * init for A to run first */ private volatile int flag = 'A'; Runnable a = () -> { while (true) { LOCK.lock(); if (flag == 'A') { System.out.println("A"); flag = 'B'; // signal B to run C_B.signal(); } else { try { // block and wait signal to invoke C_A.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; Runnable b = () -> { while (true) { LOCK.lock(); if (flag == 'B') { System.out.println("B"); flag = 'C'; // signal C to run C_C.signal(); } else { try { // block and wait signal to invoke C_B.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; Runnable c = () -> { while (true) { LOCK.lock(); if (flag == 'C') { System.out.println("C"); flag = 'A'; // signal A to run C_A.signal(); } else { try { // block and wait signal to invoke C_C.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; public void runTest() { Thread threadA = new Thread(a); Thread threadB = new Thread(b); Thread threadC = new Thread(c); threadA.start(); threadB.start(); threadC.start(); } public static void main(String[] args) { ThreadOrderWithCondition o = new ThreadOrderWithCondition(); o.runTest(); }}

转载地址:http://ygwli.baihongyu.com/

你可能感兴趣的文章
Hibernate 中get, load 区别
查看>>
java反射详解
查看>>
JPA 注解
查看>>
JQuery 简介
查看>>
Java创建对象的方法
查看>>
Extjs自定义组件
查看>>
TreeGrid 异步加载节点
查看>>
Struts2 标签库讲解
查看>>
Google Web工具包 GWT
查看>>
材料与工程学科相关软件
查看>>
MPI的人怎么用仪器
查看>>
windows 下AdNDP 安装使用
查看>>
Project 2013项目管理教程(1):项目管理概述及预备
查看>>
ssh客户端后台运行
查看>>
哥去求职,才说了一句话考官就让我出去
查看>>
一位超算中心管理人员的空间
查看>>
Weapons of Mass Destruction, Detection
查看>>
环境资源与相关词汇中英文对照
查看>>
fluorenscence aerodynamic particcle sizer
查看>>
HOME - Research Highlights & Publications
查看>>