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

java如何實現(xiàn)多線程的順序執(zhí)行

 更新時間:2021年05月16日 11:50:23   作者:Hoonick  
多線程是java的一種重要技術,但是多線程的運行是沒有絕對的順序的,那么java如何實現(xiàn)多線程的順序執(zhí)行,下面就一起來了解一下

場景

編寫一個程序,啟動三個線程,三個線程的name分別是A,B,C;,每個線程將自己的ID值在屏幕上打印5遍,打印順序是ABCABC...

使用 synchronized 實現(xiàn)

public class MyService
{
    private int flag = 1;
    
    public synchronized void printA(){
        
        while (flag != 1)
        {
            try
            {
                this.wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        flag = 2;
        this.notifyAll();
    }
    public synchronized void printB(){
        while (flag != 2)
        {
            try
            {
                this.wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        flag = 3;
        this.notifyAll();
    }
    public synchronized void printC(){
        while (flag != 3)
        {
            try
            {
                this.wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        flag = 1;
        this.notifyAll();
    }
}

這里的判斷條件中用的是 while 而不是 if , 這兩者之間有什么區(qū)別呢? 線程從 wait 狀態(tài)被喚醒,并且獲得鎖以后會繼續(xù)往下執(zhí)行,比如 A 調(diào)用nofityAll() 喚醒 B,C,這時 B與C誰會先獲得鎖是不確定的。如果是C先獲得了鎖,那么C就繼續(xù)往下執(zhí)行打印,這與我們的期望的不符。所以這里我們使用了一個 while,當C獲得鎖以后再去判斷一下flag,如果這時還不是它執(zhí)行的時候,它就再次進入wait狀態(tài)。此時A與C都是wait狀態(tài),獲得鎖的一定是B,從而實現(xiàn)我們期望的順序打印。

測試類

package testABC;

public class TestMain
{
    public static void main(String[] args)
    {
//編寫一個程序,啟動三個線程,三個線程的ID分別是A,B,C;,每個線程將自己的ID值在屏幕上打印5遍,打印順序是ABCABC...
//        MyService service = new MyService();
        MyService2 service = new MyService2();
        
        Thread A = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 5; i++)
                {
                    service.printA();
                }
            }
        });
        A.setName("A");
        Thread B = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 5; i++)
                {
                    service.printB();
                }
            }
        });
        B.setName("B");
        Thread C = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 5; i++)
                {
                    service.printC();
                }
            }
        });
        C.setName("C");
        
        A.start();
        B.start();
        C.start();
    }
}

使用 Lock 實現(xiàn)

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

public class MyService2
{
    private int flag = 1;
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    public void printA()
    {
        try
        {
            lock.lock();
            if (flag != 1)
            {
                try
                {
                    conditionA.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName());
            flag = 2;
            conditionB.signal();
        }
        finally
        {
            lock.unlock();
        }

    }

    public void printB()
    {
        try
        {
            lock.lock();
            if (flag != 2)
            {
                try
                {
                    conditionB.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName());
            flag = 3;
            conditionC.signal();
        }
        finally
        {
            lock.unlock();
        }

    }

    public void printC()
    {
        try
        {
            lock.lock();
            if (flag != 3)
            {
                try
                {
                    conditionC.await();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            System.out.print(Thread.currentThread().getName());
            flag = 1;
            conditionA.signal();
        }
        finally
        {
            lock.unlock();
        }
    }
}

當使用LOCK時可以不使用while因為condition可以喚醒指定的線程。同時注意必須先調(diào)用 conditionA.signal(); 再調(diào)用 lock.unlock(); ,否則會拋 java.lang.IllegalMonitorStateException 異常。因為在調(diào)用unlock之后,當前線程已不是此監(jiān)視器對象condition的持有者。也就是說要在此線程持有鎖定對象時,才能使用此鎖定對象。

關于此異常的博文:關于java.lang.IllegalMonitorStateException

api中的解釋

public class IllegalMonitorStateExceptionextends RuntimeException

拋出的異常表明某一線程已經(jīng)試圖等待對象的監(jiān)視器,或者試圖通知其他正在等待對象的監(jiān)視器而本身沒有指定監(jiān)視器的線程。

從以下版本開始:

JDK1.0

另請參見:
Object.notify(), Object.notifyAll(), Object.wait(), Object.wait(long), Object.wait(long, int), 序列化表格

也就是當前的線程不是此對象監(jiān)視器的所有者。也就是要在當前線程鎖定對象,才能用鎖定的對象此行這些方法,需要用到synchronized ,鎖定什么對象就用什么對象來執(zhí)行

notify(), notifyAll(),wait(), wait(long), wait(long, int)操作,否則就會報IllegalMonitorStateException異常。

例如 :

exapmle 1,鎖定方法所屬的實例對象:

public synchronized void method(){
    //然后就可以調(diào)用:this.notify()...
    //或者直接調(diào)用notify()...
}

exapmle 2,鎖定方法所屬的實例的Class:

public Class Test{
 public static synchronized void method(){
    //然后調(diào)用:Test.class.notify()...
 }
}

exapmle 3,鎖定其他對象:

public Class Test{
public Object lock = new Object();
 public static void method(){
    synchronized (lock) {
     //需要調(diào)用 lock.notify();
    } 
 }
} 

到此這篇關于java如何實現(xiàn)多線程的順序執(zhí)行的文章就介紹到這了,更多相關java 多線程順序執(zhí)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot任務之詳解郵件任務

    SpringBoot任務之詳解郵件任務

    今天給大家整理的文章是SpringBoot郵件任務的相關知識點,文中有非常詳細的介紹及代碼示例,對正在學習SpringBoot任務的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • win7下安裝 JDK 基本流程

    win7下安裝 JDK 基本流程

    這篇文章主要介紹了win7下安裝 JDK 基本流程,需要的朋友可以參考下
    2014-05-05
  • 解決dubbo錯誤ip及ip亂入問題的方法

    解決dubbo錯誤ip及ip亂入問題的方法

    今天小編就為大家分享一篇關于解決dubbo錯誤ip及ip亂入問題的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java發(fā)起http請求的完整步驟記錄

    Java發(fā)起http請求的完整步驟記錄

    這篇文章主要給大家介紹了關于Java發(fā)起http請求的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • Java 是如何利用接口避免函數(shù)回調(diào)的方法

    Java 是如何利用接口避免函數(shù)回調(diào)的方法

    本篇文章主要介紹了Java 是如何利用接口避免函數(shù)回調(diào)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • PowerJob的HashedWheelTimer工作流程源碼解讀

    PowerJob的HashedWheelTimer工作流程源碼解讀

    這篇文章主要為大家介紹了PowerJob的HashedWheelTimer工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • java的泛型你真的了解嗎

    java的泛型你真的了解嗎

    這篇文章主要為大家詳細介紹了java的泛型,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • IDEA項目中配置Maven鏡像源(下載源)的詳細過程

    IDEA項目中配置Maven鏡像源(下載源)的詳細過程

    Maven是一個能使我們的java程序開發(fā)節(jié)省時間和精力,是開發(fā)變得相對簡單,還能使開發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關于IDEA項目中配置Maven鏡像源(下載源)的詳細過程,需要的朋友可以參考下
    2024-02-02
  • Java8的Lambda表達式你真的會嗎

    Java8的Lambda表達式你真的會嗎

    這篇文章主要介紹了Java8的Lambda表達式你真的會嗎,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Spring Cloud動態(tài)配置刷新@RefreshScope與@Component的深度解析

    Spring Cloud動態(tài)配置刷新@RefreshScope與@Component的深度解析

    在現(xiàn)代微服務架構中,動態(tài)配置管理是一個關鍵需求,Spring Cloud 提供了 @RefreshScope 注解,允許應用在運行時動態(tài)更新配置,而無需重啟服務,本文深入探析Spring Cloud動態(tài)配置刷新@RefreshScope與@Component,感興趣的朋友一起看看吧
    2025-04-04

最新評論

缙云县| 且末县| 德钦县| 扬中市| 堆龙德庆县| 鹤壁市| 临泉县| 昌乐县| 南雄市| 绩溪县| 盘锦市| 萝北县| 南陵县| 额尔古纳市| 铁岭县| 舟曲县| 同德县| 西平县| 邹平县| 嫩江县| 旬邑县| 渑池县| 嘉荫县| 成安县| 鹤山市| 四平市| 独山县| 万全县| 许昌市| 收藏| 申扎县| 嘉兴市| 遵义县| 卫辉市| 古浪县| 海盐县| 贵港市| 永登县| 西城区| 灌云县| 鄢陵县|