多線程之按序打印


 

 好久沒寫博客了 。。。。

        這道題是典型的設置執行屏障的問題,要確保 two() 方法在 one() 方法之后被執行,three() 方法在 two() 方法之后被執行,對於這道問題的解法我可以直接定義一個變量variable,三個線程分別去監控variable值,當variable=0的時候執行第一個方法,variable=1的時候執行第二個方法,variable=2的時候執行第三個方法。

       當variable的值被修改時,其他線程應該要馬上能知道variable值的變化,才能做出判斷執不執行本身方法,所以variable變量要用volatile關鍵字修飾來保證線程之間的可見性,比如variable初始值為0,線程A執行方法一,執行完方法一之后把variable的值加1此時variable的值變成了1,由於variable變量用了volatile來修飾,所以線程B馬上就能知道variable的值變為了1,所以此時線程B就會調用方法二...

 1 class Foo {
 2 
 3      public Foo() {
 4         
 5     }
 6     private volatile int variable=0;
 7     public void first(Runnable printFirst) throws InterruptedException {
 8         printFirst.run();
 9         variable++;
10     }
11 
12     public void second(Runnable printSecond) throws InterruptedException {
13         while (true){
14             if(variable==1) break;
15         }
16         printSecond.run();
17         variable++;
18     }
19 
20     public void third(Runnable printThird) throws InterruptedException {
21          while (true){
22             if(variable==2) break;
23         }
24         printThird.run();
25     }
26 }

Leecode上提交結果:

多線程之按序打印
 

CountDownLatch能夠使一個線程等待其他線程完成各自的工作后再執行,這樣子我們可以讓線程B等待線程A執行完成之后再執行,線程C等待線程B執行完成之后再執行就可以實現按序打印了。

CountDownLatch通過構造函數構造一個計數器來實現,計數器的數值即為為線程的數量,每當一個線程完成了自己的任務后,計數器的值就會減1,計數器值為0時,表示CountDownLatch里面所有的線程已經完成了任務,然后在閉鎖上等待的線程就可以恢復執行任務。具體實現看代碼注釋。

classFoo{

publicFoo(){

}
privateCountDownLatcha=newCountDownLatch(1);//信號量a
privateCountDownLatchb=newCountDownLatch(1);//信號量b

publicvoidfirst(RunnableprintFirst)throwsInterruptedException{
printFirst.run();
a.countDown();//信號量a計數器減1,計數器變為0,表示信號量a執行完。
}

publicvoidsecond(RunnableprintSecond)throwsInterruptedException{
a.await();//等待信息量a的線程執行完
printSecond.run();
b.countDown();//信號量b減一,計數器變為0,表示信號量b執行完。
}

publicvoidthird(RunnableprintThird)throwsInterruptedException{
b.await();//等待信號量b的線程執行完
printThird.run();
}
}

LeeCode運行結果:

多線程之按序打印





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM