-
Notifications
You must be signed in to change notification settings - Fork 379
/
Copy pathSub1116.java
175 lines (145 loc) · 4.46 KB
/
Sub1116.java
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package com.easy.leetcode;
import java.util.function.IntConsumer;
/*
1116. 打印零与奇偶数
假设有这么一个类:
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"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/print-zero-even-odd
*/
public class Sub1116 {
public static void main(String[] args) {
//数量
int n = 2;
ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n);
IntConsumer intConsumer = (x) -> System.out.print(x);
Thread zeroThread = new ZeroThread(zeroEvenOdd, intConsumer);
Thread evenThread = new EvenThread(zeroEvenOdd, intConsumer);
Thread oddThread = new OddThread(zeroEvenOdd, intConsumer);
zeroThread.start();
evenThread.start();
oddThread.start();
}
}
class ZeroThread extends Thread {
ZeroEvenOdd zeroEvenOdd;
IntConsumer printNumber;
public ZeroThread(ZeroEvenOdd zeroEvenOdd, IntConsumer printNumber) {
this.zeroEvenOdd = zeroEvenOdd;
this.printNumber = printNumber;
}
@Override
public void run() {
try {
zeroEvenOdd.zero(printNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class EvenThread extends Thread {
ZeroEvenOdd zeroEvenOdd;
IntConsumer printNumber;
public EvenThread(ZeroEvenOdd zeroEvenOdd, IntConsumer printNumber) {
this.zeroEvenOdd = zeroEvenOdd;
this.printNumber = printNumber;
}
@Override
public void run() {
try {
zeroEvenOdd.even(printNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class OddThread extends Thread {
ZeroEvenOdd zeroEvenOdd;
IntConsumer printNumber;
public OddThread(ZeroEvenOdd zeroEvenOdd, IntConsumer printNumber) {
this.zeroEvenOdd = zeroEvenOdd;
this.printNumber = printNumber;
}
@Override
public void run() {
try {
zeroEvenOdd.odd(printNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ZeroEvenOdd {
private int n;
//生产0的数量
private int zeroCount = 0;
//信号量
private int flag = 0;
//定义Object对象为锁
private Object lock = new Object();
public ZeroEvenOdd(int n) {
this.n = n;
}
//生成0
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (lock) {
while (flag != 0) {
lock.wait();
}
printNumber.accept(0);
zeroCount++;
if (zeroCount % 2 == 0) {
flag = 2;
} else {
flag = 1;
}
lock.notifyAll();
}
}
}
//生产偶数
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i = 2; i <= n; i += 2) {
synchronized (lock) {
while (flag != 2) {
lock.wait();
}
printNumber.accept(i);
flag = 0;
lock.notifyAll();
}
}
}
//生产奇数
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i = 1; i <= n; i += 2) {
synchronized (lock) {
while (flag != 1) {
lock.wait();
}
printNumber.accept(i);
flag = 0;
lock.notifyAll();
}
}
}
}