欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java之多個線程順序循環(huán)執(zhí)行的幾種實現(xiàn)

 更新時間:2023年09月21日 17:20:40   作者:_小馬快跑_  
這篇文章主要介紹了Java之多個線程順序循環(huán)執(zhí)行的幾種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

ReentrantLock+Condition方式實現(xiàn)

public class ReentrantLock_Impl {
    private static final String FLAG_THREAD_1 = "ReentrantLock_Thread1";
    private static final String FLAG_THREAD_2 = "ReentrantLock_Thread2";
    private static final String FLAG_THREAD_3 = "ReentrantLock_Thread3";
    public static void main(String[] args) throws InterruptedException {
        //ReentrantLock構(gòu)造方法傳入true為公平鎖 false為非公平鎖
        ReentrantLock lock = new ReentrantLock(true);
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Condition condition3 = lock.newCondition();
        FairRunnable runnable = new FairRunnable(lock, condition1, condition2, condition3);
        new Thread(runnable, FLAG_THREAD_1).start();
        new Thread(runnable, FLAG_THREAD_2).start();
        new Thread(runnable, FLAG_THREAD_3).start();
    }
    static class FairRunnable implements Runnable {
        private ReentrantLock lock;
        private Condition condition1;
        private Condition condition2;
        private Condition condition3;
        public FairRunnable(ReentrantLock lock, Condition condition1, Condition condition2, Condition condition3) {
            this.lock = lock;
            this.condition1 = condition1;
            this.condition2 = condition2;
            this.condition3 = condition3;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "開始執(zhí)行");
                    Thread.sleep(1000);
                    switch (Thread.currentThread().getName()) {
                        case FLAG_THREAD_1:
                            //喚醒線程2 自身線程掛起阻塞
                            condition2.signal();
                            condition1.await();
                            break;
                        case FLAG_THREAD_2:
                            //喚醒線程3 自身線程掛起阻塞
                            condition3.signal();
                            condition2.await();
                            break;
                        case FLAG_THREAD_3:
                            //喚醒線程1 自身線程掛起阻塞
                            condition1.signal();
                            condition3.await();
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return;
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

執(zhí)行結(jié)果:

ReentrantLock_Thread1開始執(zhí)行
ReentrantLock_Thread2開始執(zhí)行
ReentrantLock_Thread3開始執(zhí)行
ReentrantLock_Thread1開始執(zhí)行
ReentrantLock_Thread2開始執(zhí)行
ReentrantLock_Thread3開始執(zhí)行
......

Synchronized+wait/notifyAll方式實現(xiàn)

public class Synchronized_Impl {
    private static final String FLAG_THREAD_1 = "Synchronized_Thread1";
    private static final String FLAG_THREAD_2 = "Synchronized_Thread2";
    private static final String FLAG_THREAD_3 = "Synchronized_Thread3";
    public static void main(String[] args) {
        FairRunnable runnable = new FairRunnable();
        new Thread(runnable, FLAG_THREAD_1).start();
        new Thread(runnable, FLAG_THREAD_2).start();
        new Thread(runnable, FLAG_THREAD_3).start();
    }
    static class FairRunnable implements Runnable {
        private volatile static int flag = 1;
        private final Object object = new Object();
        @Override
        public void run() {
            while (true) {
                synchronized (object) {
                    //如果當(dāng)前情況是:線程1&flag!=1、線程2&flag!=2、線程3&flag!=3 那當(dāng)前線程通過object.wait掛起
                    switch (Thread.currentThread().getName()) {
                        case FLAG_THREAD_1:
                            while (flag != 1) {
                                try {
                                    object.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                        case FLAG_THREAD_2:
                            while (flag != 2) {
                                try {
                                    object.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                        case FLAG_THREAD_3:
                            while (flag != 3) {
                                try {
                                    object.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            break;
                    }
                    //線程任務(wù)開始執(zhí)行
                    System.out.println(Thread.currentThread().getName() + "開始執(zhí)行");
                    try {
                        //模擬線程任務(wù)執(zhí)行
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                    switch (Thread.currentThread().getName()) {
                        case FLAG_THREAD_1:
                            //接下來該去執(zhí)行線程2
                            flag = 2;
                            break;
                        case FLAG_THREAD_2:
                            //接下來該去執(zhí)行線程3
                            flag = 3;
                            break;
                        case FLAG_THREAD_3:
                            //接下來該去執(zhí)行線程1
                            flag = 1;
                            break;
                    }
                    //喚醒所有線程
                    object.notifyAll();
                }
            }
        }
    }
}

執(zhí)行結(jié)果:

Synchronized_Thread1開始執(zhí)行
Synchronized_Thread2開始執(zhí)行
Synchronized_Thread3開始執(zhí)行
Synchronized_Thread1開始執(zhí)行
Synchronized_Thread2開始執(zhí)行
Synchronized_Thread3開始執(zhí)行
......

兩者對比

使用ReentrantLock+Condition可以更準(zhǔn)確的控制喚醒哪一個線程;

而Synchronized+wait/notifyAll的方式可能會出現(xiàn)獲取鎖的線程并不是目標(biāo)線程,此時獲取鎖的線程會重新掛起,直到獲取鎖的線程即是目標(biāo)線程為止。

比如上面代碼中:

線程1執(zhí)行完后調(diào)用notifyAll(), 此時線程2、線程3都會被喚醒并嘗試獲取鎖,如果此時線程3獲得鎖,那么線程2還要繼續(xù)等待,線程3執(zhí)行時發(fā)現(xiàn)并不是要執(zhí)行的目標(biāo)線程,那么線程3會調(diào)用wait()掛起,此時entrySet中只有線程2了,線程2也是要執(zhí)行的目標(biāo)線程,此時才會去執(zhí)行線程2,整個過程多了一次線程3的獲取與釋放鎖,原因就是wait/notifyAll并不能像ReentrantLock+Condition一樣能精確地喚醒某個線程。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • LongAdder原理及創(chuàng)建使用示例詳解

    LongAdder原理及創(chuàng)建使用示例詳解

    這篇文章主要為大家介紹了LongAdder原理及創(chuàng)建使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • SpringBoot集成Zipkin實現(xiàn)分布式全鏈路監(jiān)控

    SpringBoot集成Zipkin實現(xiàn)分布式全鏈路監(jiān)控

    這篇文章主要介紹了SpringBoot集成Zipkin實現(xiàn)分布式全鏈路監(jiān)控的方法啊,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • Java基于rest assured實現(xiàn)接口測試過程解析

    Java基于rest assured實現(xiàn)接口測試過程解析

    這篇文章主要介紹了Java基于rest assured實現(xiàn)接口測試過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • 淺談在Java中JSON的多種使用方式

    淺談在Java中JSON的多種使用方式

    這篇文章主要介紹了淺談在Java中JSON的多種使用方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • java寫入文件的幾種方法分享

    java寫入文件的幾種方法分享

    這篇文章主要介紹了java寫入文件的幾種方法,需要的朋友可以參考下
    2014-02-02
  • JAVA8 lambda表達(dá)式權(quán)威教程

    JAVA8 lambda表達(dá)式權(quán)威教程

    本文主要給大家講解Java8中最重要的一個特征之一lambda表達(dá)式,本文通過實例圖文解說給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友跟隨小編一起學(xué)習(xí)下吧
    2021-05-05
  • 帶你詳細(xì)了解Java值傳遞和引用傳遞

    帶你詳細(xì)了解Java值傳遞和引用傳遞

    這篇文章主要介紹了帶你詳細(xì)了解Java值傳遞和引用傳遞,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有一定的幫助,需要的朋友可以參考下
    2021-04-04
  • 使用Java實現(xiàn)創(chuàng)建Excel表單控件

    使用Java實現(xiàn)創(chuàng)建Excel表單控件

    在數(shù)據(jù)填報時,創(chuàng)建Excel表單控件是一項常見的任務(wù),它可以極大地簡化數(shù)據(jù)收集和處理的過程,本文主要介紹了如何使用Java實現(xiàn)創(chuàng)建Excel表單控件,感興趣的可以了解下
    2024-03-03
  • java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌

    java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌

    這篇文章主要為大家詳細(xì)介紹了java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java多線程之死鎖詳解

    Java多線程之死鎖詳解

    這篇文章主要介紹了Java多線程的死鎖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10

最新評論