
好久沒寫博客了 。。。。
這道題是典型的設置執行屏障的問題,要確保 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運行結果:
