咱們提供了一個類:異步
public class Foo {
public void one() { print("one"); }
public void two() { print("two"); }
public void three() { print("three"); }
}
三個不一樣的線程將會共用一個 Foo 實例。this
線程 A 將會調用 one() 方法
線程 B 將會調用 two() 方法
線程 C 將會調用 three() 方法
請設計修改程序,以確保 two() 方法在 one() 方法以後被執行,three() 方法在 two() 方法以後被執行。線程
示例 1:設計
輸入: [1,2,3]
輸出: "onetwothree"
解釋:
有三個線程會被異步啓動。
輸入 [1,2,3] 表示線程 A 將會調用 one() 方法,線程 B 將會調用 two() 方法,線程 C 將會調用 three() 方法。
正確的輸出是 "onetwothree"。
示例 2:code
輸入: [1,3,2]
輸出: "onetwothree"
解釋:
輸入 [1,3,2] 表示線程 A 將會調用 one() 方法,線程 B 將會調用 three() 方法,線程 C 將會調用 two() 方法。
正確的輸出是 "onetwothree"。對象
總結:全部的解法都是一個理念,不管採用何種方式,開始時必須執行first線程,而後設置條件知足second執行而first和third線程都不能執行,同時只有first線程執行完才能給與該條件,而後設置條件知足third執行而first和second線程都不能執行,同時只有second線程執行成功後才能給與該條件three
這是一個典型的執行屏障的問題,能夠經過構造屏障來實現。rem
以下圖,咱們須要構造 22 道屏障,second 線程等待 first 屏障,third 線程等待 second 屏障。:it
first 線程會釋放 first 屏障,而 second 線程會釋放 second 屏障。io
Java 中,咱們使用線程等待的方式實現執行屏障,使用釋放線程等待的方式實現屏障消除。具體代碼以下:
代碼:
Java
class Foo {
private boolean firstFinished; private boolean secondFinished; private Object lock = new Object(); public Foo() { } public void first(Runnable printFirst) throws InterruptedException { synchronized (lock) { // printFirst.run() outputs "first". Do not change or remove this line. printFirst.run(); firstFinished = true; lock.notifyAll(); } } public void second(Runnable printSecond) throws InterruptedException { synchronized (lock) { while (!firstFinished) { lock.wait(); } // printSecond.run() outputs "second". Do not change or remove this line. printSecond.run(); secondFinished = true; lock.notifyAll(); } } public void third(Runnable printThird) throws InterruptedException { synchronized (lock) { while (!secondFinished) { lock.wait(); } // printThird.run() outputs "third". Do not change or remove this line. printThird.run(); } }
}咱們使用一個 Ojbect 對象 lock 實現全部執行屏障的鎖對象,兩個布爾型對象 firstFinished,secondFinished 保存屏障消除的條件。