1. 程式人生 > >Condition 控制執行緒通訊

Condition 控制執行緒通訊

  Condition 介面描述了可能會與鎖有關聯的條件變數。這些變數在用法上與使用Object.wait 訪問的隱式監視器類似,但提供了更強大的功能。需要特別指出的是,單個Lock 可能與多個Condition 物件關聯。為了避免相容性問題,Condition 方法的名稱與對應的Object 版本中的不同。
  在Condition 物件中,與wait、notify 和notifyAll 方法對應的分別是await、signal 和signalAll。
  Condition 例項實質上被繫結到一個鎖上。要為特定Lock 例項獲得Condition 例項,請使用其newCondition() 方法。

編寫一個程式,開啟 3 個執行緒,這三個執行緒的 ID 分別為 A、B、C,每個執行緒將自己的 ID 在螢幕上列印 10 遍,要求輸出的結果必須按順序顯示。
如:ABCABCABC…… 依次遞迴

public class TestABCAlternate {

    public static void main(String[] args) {
        AlternateDemo ad = new AlternateDemo();
        new Thread(new Runnable() {
            @Override
            public
void run() { for (int i = 1; i <= 20; i++) { ad.loopA(i); } } }, "A").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopB(i); } } }, "B"
).start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopC(i); System.out.println("-----------------------------------"); } } }, "C").start(); } } class AlternateDemo{ private int number = 1; //當前正在執行執行緒的標記 private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); /** * @param totalLoop : 迴圈第幾輪 */ public void loopA(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 1){ condition1.await(); } //2. 列印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 2; condition2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopB(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 2){ condition2.await(); } //2. 列印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 3; condition3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void loopC(int totalLoop){ lock.lock(); try { //1. 判斷 if(number != 3){ condition3.await(); } //2. 列印 for (int i = 1; i <= 1; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); } //3. 喚醒 number = 1; condition1.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }