1. 程式人生 > 其它 >多執行緒問題之按序列印

多執行緒問題之按序列印

技術標籤:多執行緒

一、題目描述

我們提供了一個類:
public class Foo {
public void first() { print(“first”); }
public void second() { print(“second”); }
public void third() { print(“third”); }
}
三個不同的執行緒 A、B、C 將會共用一個 Foo 例項。
一個將會呼叫 first() 方法
一個將會呼叫 second() 方法
還有一個將會呼叫 third() 方法
請設計修改程式,以確保 second() 方法在 first() 方法之後被執行,third() 方法在 second() 方法之後被執行。

示例 1:
輸入: [1,2,3]
輸出: “firstsecondthird”
解釋:
有三個執行緒會被非同步啟動。
輸入 [1,2,3] 表示執行緒 A 將會呼叫 first() 方法,執行緒 B 將會呼叫 second() 方法,執行緒 C 將會呼叫 third() 方法。
正確的輸出是 “firstsecondthird”。
示例 2:
輸入: [1,3,2]
輸出: “firstsecondthird”
解釋:
輸入 [1,3,2] 表示執行緒 A 將會呼叫 first() 方法,執行緒 B 將會呼叫 third() 方法,執行緒 C 將會呼叫 second() 方法。
正確的輸出是 “firstsecondthird”。

二、題解
方法一:使用ReentrantLock

class Foo {
    private int number = 1;
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();
    public Foo() {
        number =
1; } public void first(Runnable printFirst) throws InterruptedException { lock.lock(); try{ if(number!=1){ condition1.await(); } // printFirst() outputs "first". Do not change or remove this line. printFirst.run(); number = 2; condition2.signal(); }finally{ lock.unlock(); } } public void second(Runnable printSecond) throws InterruptedException { lock.lock(); try{ if(number != 2){ condition2.await(); } // printSecond() outputs "second". Do not change or remove this line. printSecond.run(); number = 3; condition3.signal(); }finally{ lock.unlock(); } } public void third(Runnable printThird) throws InterruptedException { lock.lock(); try{ if(number != 3) condition3.await(); // printThird.run() outputs "third". Do not change or remove this line. printThird.run(); number = 1; condition1.signal(); }finally{ lock.unlock(); } } }

-方法二:使用Atomic

class Foo {
    private AtomicInteger firstJobDone = new AtomicInteger(0);
    private AtomicInteger secondJobDone = new AtomicInteger(0);
    public Foo() {
        
    }

    public void first(Runnable printFirst) throws InterruptedException {
        
        // printFirst() outputs "first". Do not change or remove this line.
        printFirst.run();
        firstJobDone.incrementAndGet();
    }

    public void second(Runnable printSecond) throws InterruptedException {
        while(firstJobDone.get()!=1){

        }
        // printSecond() outputs "second". Do not change or remove this line.
        printSecond.run();
        secondJobDone.incrementAndGet();
    }

    public void third(Runnable printThird) throws InterruptedException {
        while(secondJobDone.get()!=1){ 
        }
        // printThird.run() outputs "third". Do not change or remove this line.
		printThird.run();
    }
}

在這裡插入圖片描述