Java多线程实现有序输出ABC

编程入门 行业动态 更新时间:2024-10-26 11:24:48

Java<a href=https://www.elefans.com/category/jswz/34/1767532.html style=多线程实现有序输出ABC"/>

Java多线程实现有序输出ABC

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 monitorLOCK.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 monitorLOCK.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 monitorLOCK.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 runC_B.signal();} else {try {// block and wait signal to invokeC_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 runC_C.signal();} else {try {// block and wait signal to invokeC_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 runC_A.signal();} else {try {// block and wait signal to invokeC_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();}
}

更多推荐

Java多线程实现有序输出ABC

本文发布于:2024-02-25 11:42:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1698863.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多线程   Java   ABC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!