第1114題java
咱們提供了一個類: public class Foo { public void one() { print("one"); } public void two() { print("two"); } public void three() { print("three"); } } 三個不一樣的線程將會共用一個 Foo 實例。 線程 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: 輸入: [1,3,2] 輸出: "onetwothree" 解釋: 輸入 [1,3,2] 表示線程 A 將會調用 one() 方法,線程 B 將會調用 three() 方法,線程 C 將會調用 two() 方法。 正確的輸出是 "onetwothree"。 注意: 儘管輸入中的數字彷佛暗示了順序,可是咱們並不保證線程在操做系統中的調度順序。 你看到的輸入格式主要是爲了確保測試的全面性。 來源:力扣(LeetCode) 連接:https://leetcode-cn.com/problems/print-in-order
public class Sub1114 { public static void main(String[] args) throws InterruptedException { //測試用例字符串 int[] runOrder = new int[]{2, 3, 1}; //生成結果字符串 StringBuffer result = new StringBuffer(); Runnable one = () -> result.append("one"); Runnable two = () -> result.append("two"); Runnable three = () -> result.append("three"); Foo foo = new Foo(); Thread threads[] = new Thread[runOrder.length]; for (int i = 0; i < runOrder.length; ++i) { Thread thread = null; if (runOrder[i] == 1) { thread = new FirstThread(foo, one); } else if (runOrder[i] == 2) { thread = new SecondThread(foo, two); } else if (runOrder[i] == 3) { thread = new ThirdThread(foo, three); } thread.start(); threads[i] = thread; } //等侍全部線程執行完 for (int i = 0; i < threads.length; i++) { threads[i].join(); } //輸出結果串 System.out.println(result.toString()); } } class FirstThread extends Thread { Foo foo; Runnable runnable; public FirstThread(Foo h2o, Runnable runnable) { this.foo = h2o; this.runnable = runnable; } @Override public void run() { try { foo.first(runnable); } catch (InterruptedException e) { e.printStackTrace(); } } } class SecondThread extends Thread { Foo foo; Runnable runnable; public SecondThread(Foo h2o, Runnable runnable) { this.foo = h2o; this.runnable = runnable; } @Override public void run() { try { foo.second(runnable); } catch (InterruptedException e) { e.printStackTrace(); } } } class ThirdThread extends Thread { Foo foo; Runnable runnable; public ThirdThread(Foo h2o, Runnable runnable) { this.foo = h2o; this.runnable = runnable; } @Override public void run() { try { foo.third(runnable); } catch (InterruptedException e) { e.printStackTrace(); } } } class Foo { //信號量 private int flag = 0; //定義Object對象爲鎖 private Object lock = new Object(); public Foo() { } public void first(Runnable printFirst) throws InterruptedException { synchronized (lock) { //若是flag不爲0則讓first線程等待,while循環控制first線程若是不滿住條件就一直在while代碼塊中,防止出現中途跳入,執行下面的代碼,其他線程while循環同理 while (flag != 0) { lock.wait(); } printFirst.run(); //定義成員變量爲 1 flag = 1; //喚醒其他全部的線程 lock.notifyAll(); } } public void second(Runnable printSecond) throws InterruptedException { synchronized (lock) { //若是成員變量不爲1則讓二號等待 while (flag != 1) { lock.wait(); } printSecond.run(); //若是成員變量爲 1 ,則表明first線程剛執行完,因此執行second,而且改變成員變量爲 2 flag = 2; //喚醒其他全部的線程 lock.notifyAll(); } } public void third(Runnable printThird) throws InterruptedException { synchronized (lock) { //若是flag不等於2 則一直處於等待的狀態 while (flag != 2) { lock.wait(); } //若是成員變量爲 2 ,則表明second線程剛執行完,因此執行third,而且改變成員變量爲 0 printThird.run(); flag = 0; lock.notifyAll(); } } }