为有牺牲多壮志,敢教日月换新天。

[Java]LeetCode1116. 打印零与奇偶数 | Print Zero Even Odd

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

Suppose you are given the following code:

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:

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.

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"


假设有这么一个类:

class ZeroEvenOdd {
  public ZeroEvenOdd(int n) { ... }  // 构造函数
public void zero(printNumber) { ... } // 仅打印出 0
public void even(printNumber) { ... } // 仅打印出 偶数
public void odd(printNumber) { ... } // 仅打印出 奇数
}
相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程:

线程 A 将调用 zero(),它只输出 0 。
线程 B 将调用 even(),它只输出偶数。
线程 C 将调用 odd(),它只输出奇数。
每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。

示例 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 }

 

posted @ 2019-08-02 16:14  为敢技术  阅读(862)  评论(0编辑  收藏  举报