1116. Print Zero Even Odd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class ZeroEvenOdd {
private int n;
private final Object lock;
private boolean shouldPrintZero;
private boolean shouldPrintOdd;

public ZeroEvenOdd(int n) {
this.n = n;
this.lock = new Object();
this.shouldPrintZero = true;
this.shouldPrintOdd = true;
}

// order: zero, odd, zero, even

// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (lock) {
while (!shouldPrintZero) {
lock.wait();
}

printNumber.accept(0);

shouldPrintZero = false;
lock.notifyAll();
}
}
}

public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 2; i <= n; i += 2) {
synchronized (lock) {
while (shouldPrintZero || shouldPrintOdd) {
lock.wait();
}

printNumber.accept(i);

shouldPrintZero = true;
shouldPrintOdd = true;
lock.notifyAll();
}
}
}

public synchronized void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i += 2) {
synchronized (lock) {
while (shouldPrintZero || !shouldPrintOdd) {
lock.wait();
}

printNumber.accept(i);

shouldPrintZero = true;
shouldPrintOdd = false;
lock.notifyAll();
}
}
}

}

注意该题在调用时三个线程只会调用一次,所以需要在方法内部进行 for 循环处理。

References

1116. Print Zero Even Odd