如何实现三个线程轮流输出1-100, 这个问题在面试中经常会问到,之前有写过,但不是很合理,最近有点新想法重新写了一稿,直接看代码吧。

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
package com.hunter.train.common.print;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ConcurrentPrinter {
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

private static final int MAX_COUNT = 100;
private static final int THREAD_NUM = 3;

public static class Printer implements Runnable{
private Counter counter;
private ReentrantLock lock;
private Condition self;
private Condition next;

public Printer(Counter counter, ReentrantLock lock, Condition self, Condition next) {
this.counter = counter;
this.lock = lock;
this.self = self;
this.next = next;
}


@Override
public void run() {
lock.lock();

try {
while (counter.getCount() < 100) {
System.out.println(Thread.currentThread().getName() + ":" + counter.addAndGet());
// 这样另外的线程就能拿到锁了
next.signal();
// 如果满足这个条件,说明已经不会再轮到自己了,也就没必要再等了
if (counter.getCount() > MAX_COUNT - THREAD_NUM) {
break;
} else {
self.await();
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}


public static class Counter{
private int count;

public Counter(int count) {
this.count = count;
}

public int getCount(){
return count;
}

public int addAndGet() {
return ++count;
}
}

public static void main(String[] args) {
Counter counter = new Counter(0);

ReentrantLock lock = new ReentrantLock(true);
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();

executor.submit(new Printer(counter, lock, condition1, condition2));
executor.submit(new Printer(counter, lock, condition2, condition3));
executor.submit(new Printer(counter, lock, condition3, condition1));
executor.shutdown();
}
}
Contents