[Java]LeetCode1116. 打印零與奇偶數 | Print Zero Even Odd

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Suppose you are given the following code:java

class ZeroEvenOdd {
  public ZeroEvenOdd(int n) { ... }  // constructor
public void zero(printNumber) { ... } // only output 0's
public void even(printNumber) { ... } // only output even numbers
public void odd(printNumber) { ... } // only output odd numbers
}
The same instance of ZeroEvenOdd will be passed to three different threads:git

Thread A will call zero() which should only output 0's.
Thread B will call even() which should only ouput even numbers.
Thread C will call odd() which should only output odd numbers.
Each of the thread is given a printNumber method to output an integer. Modify the given program to output the series 010203040506... where the length of the series must be 2n.github

Example 1:微信

Input: n = 2
Output: "0102"
Explanation: There are three threads being fired asynchronously. One of them calls zero(), the other calls even(), and the last one calls odd(). "0102" is the correct output.
Example 2:異步

Input: n = 5
Output: "0102030405"async


假設有這麼一個類:函數

class ZeroEvenOdd {
  public ZeroEvenOdd(int n) { ... }  // 構造函數
public void zero(printNumber) { ... } // 僅打印出 0
public void even(printNumber) { ... } // 僅打印出 偶數
public void odd(printNumber) { ... } // 僅打印出 奇數
}
相同的一個 ZeroEvenOdd 類實例將會傳遞給三個不一樣的線程:ui

線程 A 將調用 zero(),它只輸出 0 。
線程 B 將調用 even(),它只輸出偶數。
線程 C 將調用 odd(),它只輸出奇數。
每一個線程都有一個 printNumber 方法來輸出一個整數。請修改給出的代碼以輸出整數序列 010203040506... ,其中序列的長度必須爲 2n。this

示例 1:

輸入:n = 2
輸出:"0102"
說明:三條線程異步執行,其中一個調用 zero(),另外一個線程調用 even(),最後一個線程調用odd()。正確的輸出爲 "0102"。
示例 2:

輸入:n = 5
輸出:"0102030405"


4ms

 1 import java.util.concurrent.*;
 2 
 3 class ZeroEvenOdd {
 4     private int n;
 5     Semaphore s1, s2, s3;
 6     
 7     public ZeroEvenOdd(int n) {
 8         this.n = n;
 9         s1 = new Semaphore(1);
10         s2 = new Semaphore(0);
11         s3 = new Semaphore(0);
12     }
13 
14     // printNumber.accept(x) outputs "x", where x is an integer.
15     public void zero(IntConsumer printNumber) throws InterruptedException {
16         for (int i = 0; i < n; i++) {
17             s1.acquire();
18             printNumber.accept(0);
19             if (i % 2 == 0) {
20                 s3.release();
21             } else {
22                 s2.release();
23             }
24         }
25     }
26 
27     public void even(IntConsumer printNumber) throws InterruptedException {
28         for (int i = 2; i <= n; i += 2) {
29             s2.acquire();
30             printNumber.accept(i);
31             s1.release();
32         }
33     }
34 
35     public void odd(IntConsumer printNumber) throws InterruptedException {
36         for (int i = 1; i <= n; i += 2) {
37             s3.acquire();
38             printNumber.accept(i);
39             s1.release();
40         }
41     }
42 }

7ms

 1 import java.util.concurrent.locks.ReentrantLock;
 2 import java.util.concurrent.locks.Condition;
 3 import java.util.function.IntConsumer;
 4 class ZeroEvenOdd {
 5     private int n;
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition z = lock.newCondition();
 8     private Condition e = lock.newCondition();
 9     private Condition o = lock.newCondition();
10     private boolean isZero = true;
11     private boolean isOld = true;
12     public ZeroEvenOdd(int n) {
13         this.n = n;
14     }
15 
16     // printNumber.accept(x) outputs "x", where x is an integer.
17     public void zero(IntConsumer printNumber) throws InterruptedException {
18         lock.lock();
19         for (int i = 1; i <= n; i++) {
20             if (!isZero) {
21                 z.await();
22             }
23             printNumber.accept(0);
24             isZero = false;
25             if (i%2!=0) {
26                 o.signal();
27             } else {
28                 e.signal();
29             }
30         }
31         lock.unlock();
32     }
33 
34     public void even(IntConsumer printNumber) throws InterruptedException {
35         lock.lock();
36         for (int i = 2; i <= n; i+=2) {
37             if (isZero||isOld) {
38                 e.await();
39             }
40             printNumber.accept(i);
41             isZero = true;
42             isOld = true;
43             z.signal();
44         }
45         lock.unlock();
46     }
47 
48     public void odd(IntConsumer printNumber) throws InterruptedException {
49         lock.lock();
50         for (int i = 1; i <= n; i+=2) {
51             if (isZero||!isOld) {
52                 o.await();
53             }
54             printNumber.accept(i);
55             isZero = true;
56             isOld=false;
57             z.signal();
58         }
59         lock.unlock();
60     }
61 }

8ms

 1 import java.util.concurrent.locks.*;
 2 class ZeroEvenOdd {
 3     private int n;
 4     private volatile boolean e = false;
 5     private volatile boolean o = false;
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition zeroCondition = lock.newCondition();
 8     private Condition evenCondition = lock.newCondition();
 9     private Condition oddCondition = lock.newCondition();
10 
11 
12     public ZeroEvenOdd(int n) {
13         this.n = n;
14     }
15 
16     // printNumber.accept(x) outputs "x", where x is an integer.
17     public void zero(IntConsumer printNumber) throws InterruptedException {
18         for (int i = 1; i <= n; i++) {
19             lock.lock();
20             try {
21                 if (i != 1) {
22                     zeroCondition.await();
23                 }
24                 printNumber.accept(0);
25                 if (isOdd(i)) {
26                     o = true;
27                     oddCondition.signal();
28                 } else {
29                     e = true;
30                     evenCondition.signal();
31                 }
32             } finally {
33                 lock.unlock();
34             }
35         }
36     }
37 
38     public void even(IntConsumer printNumber) throws InterruptedException {
39         for (int i = 2; i <= n; i += 2) {
40             lock.lock();
41             try {
42                 while (!e) {
43                     evenCondition.await();
44                 }
45                 e = false;
46                 printNumber.accept(i);
47                 zeroCondition.signal();
48             } finally {
49                 lock.unlock();
50             }
51         }
52 
53     }
54 
55     public void odd(IntConsumer printNumber) throws InterruptedException {
56         for (int i = 1; i <= n; i += 2) {
57             lock.lock();
58             try {
59                 while (!o) {
60                     oddCondition.await();
61                 }
62                 o = false;
63                 printNumber.accept(i);
64                 zeroCondition.signal();
65             } finally {
66                 lock.unlock();
67             }
68         }
69     }
70 
71     private static boolean isOdd(final int number) {
72         return (number & 1) == 1;
73     }
74 }
相關文章
相關標籤/搜索