併發編程ABC循環打印問題實現,JUC

參考文檔:https://www.cnblogs.com/linkworld/p/7819270.html
參考視頻:
https://www.bilibili.com/video/BV14W411u7gB?from=search&seid=924727718441316160

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author:CarlosXu
 * @Date:2019/10/25
 */
// 編寫一個程序,開啓3個線程,這三個線程的 ID 分別爲 A, B, C, 每個線程將自己的 ID 在屏幕上打印10遍,
// 要求輸出的結果必須按順序顯示:
// 如: ABCABCABC... 依次遞歸
public class TestABCAlernate {
    public static void main(String[] args) {
        AlernateDemo demo=new AlernateDemo();
        //創建三個線程ABC
        new Thread(()->{
            for (int i=0;i<5;i++){
                demo.loopA(i);
            }
        },"A").start();

        new Thread(()->{
            for (int i=0;i<5;i++){
                demo.loopB(i);
            }
        },"B").start();

        new Thread(()->{
            for (int i=0;i<5;i++){
                demo.loopC(i);
            }
        },"C").start();
    }
}

class AlernateDemo {
    //標記當前正在執行的線程
    private int num = 1;
	//同步鎖
    private Lock lock = new ReentrantLock();
    //lock鎖的喚醒機制
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

	//線程A ,total表示循環幾輪
    public void loopA(int total) {
        lock.lock();
        try {
            if (num != 1) {
            //如果不是當前線程,當前線程等待,等待其他線程喚醒
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + "===" + num + "===" + total);
            //喚醒線程B
            num = 2;
            condition2.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
//線程B ,total表示循環幾輪
    public void loopB(int total) {
        lock.lock();
        try {
            if (num != 2) {
             //如果不是當前線程,當前線程等待,等待其他線程喚醒
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName() + "===" + num + "===" + total);
            //喚醒線程C
            num = 3;
            condition3.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
//線程C ,total表示循環幾輪
    public void loopC(int total) {
        lock.lock();
        try {
            if (num != 3) {
             //如果不是當前線程,當前線程等待,等待其他線程喚醒
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName() + "===" + num + "===" + total);
            //喚醒線程 A
            num = 1;
            condition1.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章