forked from algorithm024/algorithm024
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathZeroEvenOddCondition.java
More file actions
115 lines (107 loc) · 3.44 KB
/
ZeroEvenOddCondition.java
File metadata and controls
115 lines (107 loc) · 3.44 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.IntConsumer;
/**
* https://leetcode-cn.com/problems/print-zero-even-odd/
*
* Semaphore 解决
*/
public class ZeroEvenOddCondition {
public static void main(String[] args) {
ZeroEvenOddCondition zeroEvenOddSemaphore = new ZeroEvenOddCondition(4);
new Thread(() -> {
try {
zeroEvenOddSemaphore.zero(new IntConsumer() {
@Override
public void accept(int value) {
System.out.print(value);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
},"A").start();
new Thread(() -> {
try {
zeroEvenOddSemaphore.even(new IntConsumer() {
@Override
public void accept(int value) {
System.out.print(value);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
},"B").start();
new Thread(() -> {
try {
zeroEvenOddSemaphore.odd(new IntConsumer() {
@Override
public void accept(int value) {
System.out.print(value);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
},"C").start();
}
private int n;
// 记录打印数字
private volatile Integer incre = 1;
private volatile int flag = 1;
private ReentrantLock lock;
private Condition conditionA;
private Condition conditionB;
private Condition conditionC;
public ZeroEvenOddCondition(int n) {
this.n = n;
this.lock = new ReentrantLock();
this.conditionA = this.lock.newCondition();
this.conditionB = this.lock.newCondition();
this.conditionC = this.lock.newCondition();
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
while (flag != 1) {
conditionA.await();
}
printNumber.accept(0);
if (incre % 2 == 0) {
flag = 2;
conditionB.signal();
}else {
flag = 3;
conditionC.signal();
}
lock.unlock();
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
while ((n % 2 == 0 && incre <= n) || (n % 2 == 1 && incre <= n - 1)) {
lock.lock();
while (flag != 2) {
conditionB.await();
}
printNumber.accept(incre++);
flag = 1;
conditionA.signal();
lock.unlock();
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
while ((n % 2 == 0 && incre <= n - 1 ) || (n % 2 == 1 && incre <= n)) {
lock.lock();
while (flag != 3) {
conditionC.await();
}
printNumber.accept(incre++);
flag = 1;
conditionA.signal();
lock.unlock();
}
}
}