多線程交替順序執(zhí)行

多線程交替順序執(zhí)行

1.知識(shí)補(bǔ)充

1.1Condition 控制線程通信

Condition 接口描述了可能會(huì)與鎖有關(guān)聯(lián)的條件變量。這些變量在用法上與使用Object.wait 訪問的隱式監(jiān)視器類似,但提供了更強(qiáng)大的功能。需要特別指出的是,單個(gè)Lock 可能與多個(gè)Condition 對(duì)象關(guān)聯(lián)。為了避免兼容性問題,Condition 方法的名稱與對(duì)應(yīng)的Object 版本中的不同。
.在Condition 對(duì)象中,與wait、notify 和notifyAll 方法對(duì)應(yīng)的分別是await、signal 和signalAll。
.Condition 實(shí)例實(shí)質(zhì)上被綁定到一個(gè)鎖上。要為特定Lock 實(shí)例獲得Condition 實(shí)例,請(qǐng)使用其newCondition() 方法。

1.2面試題

編寫一個(gè)程序,開啟3 個(gè)線程,這三個(gè)線程的ID 分別為A、B、C,每個(gè)線程將自己的ID 在屏幕上打印10 遍,要求輸出的結(jié)果必須按順序顯示。
如:ABCABCABC…… 依次遞歸

1.3解決方法

在這里,我們需要使用到上面的condition對(duì)進(jìn)程進(jìn)行控制,使其交替順序執(zhí)行

2.代碼實(shí)現(xiàn)

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

/**
 * @author juntech
 * @version ${version}
 * @date 2019/12/19 16:03
 * @ClassName 類名
 * @Descripe 描述
 */
public class TestABCAlternateDemo {
    public static void main(String[] args) {
        ABCAlterNate ad = new ABCAlterNate();
        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 ABCAlterNate {
        private int num = 1; //正在執(zhí)行的標(biāo)志
        private Lock lock = new ReentrantLock();
        //開啟3個(gè)condition通信
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();


        /**
         * @param totalLoop 循環(huán)次數(shù)
         */
        public void loopB(int totalLoop) {
            //加鎖
            lock.lock();

            try {
                //1.判斷
                if (num != 2) {
                    conditionB.await();
                }
                //2.循環(huán)打印
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
                }
                //3.喚醒
                num = 3;
                conditionC.signal();


            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void loopC(int totalLoop) {
            //加鎖
            lock.lock();

            try {
                //1.判斷
                if (num != 3) {
                    conditionC.await();
                }
                //2.循環(huán)打印
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
                }
                //3.喚醒
                num = 1;
                conditionA.signal();


            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void loopA(int totalLoop) {
            //加鎖
            lock.lock();

            try {
                //1.判斷
                if (num != 1) {
                    conditionA.await();
                }
                //2.循環(huán)打印
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
                }
                //3.喚醒
                num = 2;
                conditionB.signal();


            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }


運(yùn)行,控制臺(tái)輸出:

A   0   1
A   1   1
A   2   1
A   3   1
A   4   1
B   0   1
B   1   1
B   2   1
B   3   1
B   4   1
C   0   1
C   1   1
C   2   1
C   3   1
C   4   1
C   5   1
C   6   1
C   7   1
C   8   1
C   9   1
C   10  1
C   11  1
C   12  1
C   13  1
C   14  1
C   15  1
C   16  1
C   17  1
C   18  1
C   19  1
----------------------------
A   0   2
A   1   2
A   2   2
A   3   2
A   4   2
B   0   2
B   1   2
B   2   2
B   3   2
B   4   2
C   0   2
C   1   2
C   2   2
C   3   2
C   4   2
C   5   2
C   6   2
C   7   2
C   8   2
C   9   2
C   10  2
C   11  2
C   12  2
C   13  2
C   14  2
C   15  2
C   16  2
C   17  2
C   18  2
C   19  2
----------------------------
A   0   3
A   1   3
A   2   3
A   3   3
A   4   3
B   0   3
B   1   3
B   2   3
B   3   3
B   4   3
C   0   3
C   1   3
C   2   3
C   3   3
C   4   3
C   5   3
C   6   3
C   7   3
C   8   3
C   9   3
C   10  3
C   11  3
C   12  3
C   13  3
C   14  3
C   15  3
C   16  3
C   17  3
C   18  3
C   19  3
----------------------------
A   0   4
.....

3.致謝

感謝各位coder抽出寶貴的時(shí)間來(lái)觀看這篇文章!更多詳情請(qǐng)?jiān)L問:juntech

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容