Skip to content

Commit d208630

Browse files
committed
add order_print_num.md in codeinterview.
1 parent 75eff78 commit d208630

1 file changed

Lines changed: 213 additions & 0 deletions

File tree

codeinterview/order_print_num.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
问题分析:首先我们需要看清楚题目,多线程、顺序打印、然后就是几个线程交替顺序打印;
2+
3+
首先看下输出结果:
4+
5+
```
6+
7+
thread-0:0
8+
thread-1:1
9+
thread-2:2
10+
thread-0:3
11+
thread-1:4
12+
thread-2:5
13+
thread-0:6
14+
thread-1:7
15+
thread-2:8
16+
thread-0:9
17+
thread-1:10
18+
thread-2:11
19+
thread-0:12
20+
thread-1:13
21+
thread-2:14
22+
thread-0:15
23+
thread-1:16
24+
thread-2:17
25+
thread-0:18
26+
thread-1:19
27+
thread-2:20
28+
thread-0:21
29+
thread-1:22
30+
thread-2:23
31+
thread-0:24
32+
thread-1:25
33+
thread-2:26
34+
thread-0:27
35+
thread-1:28
36+
thread-2:29
37+
thread-0:30
38+
thread-1:31
39+
thread-2:32
40+
thread-0:33
41+
thread-1:34
42+
thread-2:35
43+
thread-0:36
44+
thread-1:37
45+
thread-2:38
46+
thread-0:39
47+
thread-1:40
48+
thread-2:41
49+
thread-0:42
50+
thread-1:43
51+
thread-2:44
52+
thread-0:45
53+
thread-1:46
54+
thread-2:47
55+
thread-0:48
56+
thread-1:49
57+
thread-2:50
58+
thread-0:51
59+
thread-1:52
60+
thread-2:53
61+
thread-0:54
62+
thread-1:55
63+
thread-2:56
64+
thread-0:57
65+
thread-1:58
66+
thread-2:59
67+
thread-0:60
68+
thread-1:61
69+
thread-2:62
70+
thread-0:63
71+
thread-1:64
72+
thread-2:65
73+
thread-0:66
74+
thread-1:67
75+
thread-2:68
76+
thread-0:69
77+
thread-1:70
78+
thread-2:71
79+
thread-0:72
80+
thread-1:73
81+
thread-2:74
82+
thread-0:75
83+
thread-1:76
84+
thread-2:77
85+
thread-0:78
86+
thread-1:79
87+
thread-2:80
88+
thread-0:81
89+
thread-1:82
90+
thread-2:83
91+
thread-0:84
92+
thread-1:85
93+
thread-2:86
94+
thread-0:87
95+
thread-1:88
96+
thread-2:89
97+
thread-0:90
98+
thread-1:91
99+
thread-2:92
100+
thread-0:93
101+
thread-1:94
102+
thread-2:95
103+
thread-0:96
104+
thread-1:97
105+
thread-2:98
106+
thread-0:99
107+
thread-1:100
108+
109+
```
110+
111+
其实这个题目的重点就是怎么实现多个线程交替顺序打印,想一想,这里我们需要用到的就是线程间的通信,然后怎么通信呢?
112+
我们可以通过 synchronized + wait + notifyAll,或者 ReentrantLock + Condition + await + signalAll;
113+
114+
知道了线程间怎么通信,然后就是在每个线程内部怎么实现了,是不是多个线程共用一把锁,然后自然数0-100是公共资源,让3个线程去消费;
115+
116+
我们可以每个线程加上一个标号:0,1,2,来表示具体是哪个线程;
117+
通过一个计数器对3进行求余,余数和具体的线程标号去比较,只有当余数和线程标号相等的时候才进行打印(不等加入等待队列),打印完计数器进行自增;
118+
然后唤醒等待队列里面线程去获取锁,获取锁成功则继续执行以上步骤,否则加入锁的同步队列中,等待上一个线程唤醒;
119+
120+
`用 synchronized 锁实现如下:`
121+
122+
```java
123+
class PrintThread1 implements Runnable {
124+
private static final Object LOCK = new Object();
125+
126+
private static int count = 0; // 计数,同时确定线程是否要加入等待队列,还是可以直接去资源队列里面去获取数据进行打印
127+
private LinkedList<Integer> queue;
128+
private Integer threadNo;
129+
130+
public PrintThread1(LinkedList<Integer> queue, Integer threadNo) {
131+
this.queue = queue;
132+
this.threadNo = threadNo;
133+
}
134+
135+
@Override
136+
public void run() {
137+
while (true) {
138+
synchronized (LOCK) {
139+
while (count % 3 != this.threadNo) {
140+
if (count >= 101) {
141+
break;
142+
}
143+
try {
144+
LOCK.wait();
145+
} catch (InterruptedException e) {
146+
e.printStackTrace();
147+
}
148+
}
149+
150+
if (count >= 101) {
151+
break;
152+
}
153+
154+
Integer val = this.queue.poll();
155+
System.out.println("thread-" + this.threadNo + ":" + val);
156+
count++;
157+
158+
LOCK.notifyAll();
159+
}
160+
}
161+
}
162+
}
163+
```
164+
165+
`用 ReentrantLock 锁实现如下:`
166+
167+
```java
168+
class PrintThread2 implements Runnable {
169+
private static final ReentrantLock lock = new ReentrantLock();
170+
private static final Condition c = lock.newCondition();
171+
172+
private static int count = 0; //作为计数,同时也作为资源;因为这道题目是自然数作为资源,所以正好可以公用;
173+
private Integer threadNo;
174+
175+
public PrintThread2(Integer threadNo) {
176+
this.threadNo = threadNo;
177+
}
178+
179+
@Override
180+
public void run() {
181+
while (true) {
182+
try {
183+
lock.lock();
184+
while (count % 3 != this.threadNo) {
185+
if (count >= 101) {
186+
break;
187+
}
188+
try {
189+
c.await();
190+
} catch (InterruptedException e) {
191+
e.printStackTrace();
192+
}
193+
}
194+
195+
if (count >= 101) {
196+
break;
197+
}
198+
System.out.println("thread-" + this.threadNo + ":" + count);
199+
count++;
200+
201+
c.signalAll();
202+
203+
} finally {
204+
lock.unlock();
205+
}
206+
}
207+
}
208+
}
209+
```
210+
211+
`具体代码实现:`
212+
213+
参见:[code](https://github.com/joyang1/JavaInterview/blob/master/codeinterview/src/main/java/cn/tommyyang/multithread/OrderPrintNum.java)

0 commit comments

Comments
 (0)