题目
现有函数 printNumber
可以用一个整数参数调用,并输出该整数到控制台。
- 例如,调用
printNumber(7)
将会输出7
到控制台。
给你类 ZeroEvenOdd
的一个实例,该类中有三个函数:zero
、even
和 odd
。ZeroEvenOdd
的相同实例将会传递给三个不同线程:
- 线程 A: 调用
zero()
,只输出0
- 线程 B: 调用
even()
,只输出偶数 - 线程 C: 调用
odd()
,只输出奇数
修改给出的类,以输出序列 "010203040506..."
,其中序列的长度必须为 2n
。
实现 ZeroEvenOdd
类:
ZeroEvenOdd(int n)
用数字n
初始化对象,表示需要输出的数。void zero(printNumber)
调用printNumber
以输出一个 0 。void even(printNumber)
调用printNumber
以输出偶数。void odd(printNumber)
调用printNumber
以输出奇数。
示例 1:
输入:n = 2
输出:"0102"
解释:三条线程异步执行,其中一个调用 zero(),另一个线程调用 even(),最后一个线程调用odd()。正确的输出为 "0102"。
1
2
3
2
3
示例 2:
输入:n = 5
输出:"0102030405"
1
2
2
提示:
1 <= n <= 1000
题解
java
class ZeroEvenOdd {
private int n;
private Semaphore zero = new Semaphore(1);
private Semaphore odd = new Semaphore(1);
private Semaphore even = new Semaphore(1);
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
even.acquire();
odd.acquire();
for (int i = 0; i < this.n; i++) {
zero.acquire();
printNumber.accept(0);
if ((i & 1) == 0) {
odd.release();
} else {
even.release();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= this.n; i++) {
if ((i & 1) == 0) {
even.acquire();
printNumber.accept(i);
zero.release();
}
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= this.n; i++) {
if ((i & 1) == 1) {
odd.acquire();
printNumber.accept(i);
zero.release();
}
}
}
}
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
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