leetcode1116

题目类型:并发

题目:打印零与奇偶数

题目描述:

相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程:

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

 1 class ZeroEvenOdd {
 2     private int n;
 3     private boolean zeroTag = true;// true:打印0,false:打印非0
 4     private int number = 0;// 累加数字
 5     private Object lock = new Object();
 6 
 7     public ZeroEvenOdd(int n) {
 8         this.n = n;
 9     }
10 
11     // printNumber.accept(x) outputs "x", where x is an integer.
12     public void zero(IntConsumer printNumber) throws InterruptedException {
13         for (int j = 1; j <= n; j++) {
14             synchronized (lock) {
15                 while (!zeroTag) {
16                     lock.wait();
17                 }
18                 printNumber.accept(0);
19                 zeroTag = false;
20                 number = j;
21                 lock.notifyAll();
22             }
23         }
24     }
25 
26     public void even(IntConsumer printNumber) throws InterruptedException {
27         for (int j = 2; j <= n; j = j + 2) {
28             synchronized (lock) {
29                 while (zeroTag || number != j) {
30                     lock.wait();
31                 }
32                 printNumber.accept(j);
33                 zeroTag = true;
34                 lock.notifyAll();
35             }
36         }
37     }
38 
39     public void odd(IntConsumer printNumber) throws InterruptedException {
40         for (int j = 1; j <= n; j = j + 2) {
41             synchronized (lock) {
42                 while (zeroTag || number != j) {
43                     lock.wait();
44                 }
45                 printNumber.accept(j);
46                 zeroTag = true;
47                 lock.notifyAll();
48             }
49         }
50     }
51 }
原文地址:https://www.cnblogs.com/asenyang/p/14378060.html