最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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構造方法傳入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í)行結果:

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) {
                    //如果當前情況是:線程1&flag!=1、線程2&flag!=2、線程3&flag!=3 那當前線程通過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;
                    }
                    //線程任務開始執(zhí)行
                    System.out.println(Thread.currentThread().getName() + "開始執(zhí)行");
                    try {
                        //模擬線程任務執(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í)行結果:

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

兩者對比

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

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

比如上面代碼中:

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

總結

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

相關文章

  • 帶你了解Java數(shù)據(jù)結構和算法之無權無向圖

    帶你了解Java數(shù)據(jù)結構和算法之無權無向圖

    這篇文章主要為大家介紹了Java數(shù)據(jù)結構和算法之無權無向圖?,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Java如何跳出當前多重循環(huán)你知道嗎

    Java如何跳出當前多重循環(huán)你知道嗎

    這篇文章主要為大家介紹了Java跳出當前多重循環(huán),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 在Java中關閉SQL執(zhí)行日志來優(yōu)化服務器性能

    在Java中關閉SQL執(zhí)行日志來優(yōu)化服務器性能

    Java應用程序中,數(shù)據(jù)庫操作是一個常見的任務,如果不適當?shù)靥幚鞸QL執(zhí)行日志,可能會導致不必要的性能損失,SQL執(zhí)行日志通常由數(shù)據(jù)庫連接池、ORM框架(如Hibernate、MyBatis)、或者應用服務器的內(nèi)置日志機制生成,本文將探討如何在Java中關閉SQL執(zhí)行日志,提升應用性能和效率
    2024-11-11
  • File.createTempFile創(chuàng)建臨時文件的示例詳解

    File.createTempFile創(chuàng)建臨時文件的示例詳解

    這篇文章主要介紹了File.createTempFile創(chuàng)建臨時文件的示例詳解,在默認臨時文件目錄中創(chuàng)建一個空文件,使用給定前綴和后綴生成其名稱。 如果感興趣來了解一下
    2020-07-07
  • 使用SpringBoot跨系統(tǒng)調(diào)用接口的方案

    使用SpringBoot跨系統(tǒng)調(diào)用接口的方案

    這篇文章主要介紹了使用SpringBoot跨系統(tǒng)調(diào)用接口的方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 淺談HttpClient、okhttp和RestTemplate的區(qū)別

    淺談HttpClient、okhttp和RestTemplate的區(qū)別

    這篇文章主要介紹了HttpClient、okhttp和RestTemplate的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系

    Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系

    這篇文章主要介紹了Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系,文章通過圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考幾種,感興趣的小伙伴可以參考一下
    2022-09-09
  • minio的原理、部署、操作方法(十分鐘精通MinIO)

    minio的原理、部署、操作方法(十分鐘精通MinIO)

    MinIO是一個簡單易用的云存儲服務,可以將文件上傳到互聯(lián)網(wǎng)上,方便在不同地方訪問,部署MinIO需要拉取鏡像、啟動端口、設置賬號密碼和映射文件地址,在Spring?Boot中集成MinIO,需要添加依賴、創(chuàng)建客戶端并進行單元測試,感興趣的朋友一起看看吧
    2025-02-02
  • Java編程中的一些常見問題匯總

    Java編程中的一些常見問題匯總

    這篇文章主要介紹了Java編程中的一些常見問題匯總,本文總結的都是一些Java代碼中比較典型的錯誤,需要的朋友可以參考下
    2014-09-09
  • 帶你了解Java的類和對象

    帶你了解Java的類和對象

    下面小編就為大家?guī)硪黄胬斫釰ava類和對象。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09

最新評論

北辰区| 闽侯县| 金寨县| 青河县| 获嘉县| 科尔| 孙吴县| 芜湖县| 昌邑市| 广河县| 广河县| 灵武市| 永仁县| 博野县| 上蔡县| 桓仁| 汉沽区| 石城县| 安阳县| 郎溪县| 广汉市| 紫阳县| 寻甸| 玛曲县| 南召县| 义马市| 七台河市| 鄱阳县| 台北县| 永宁县| 榆林市| 肃北| 咸丰县| 大洼县| 宜兴市| 东丰县| 上思县| 福鼎市| 乃东县| 徐汇区| 通州区|