最近看到个Java多线程的面试题,要求3个线程,分别负责打印A/B/C,要求三个线程按照ABC的顺序输出N次
。
然后下面是我的解题思路:
首先,多线程问题,无脑起一个ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize,maxPoolSize,1,TimeUnit.MINUTES, new LinkedBlockingQueue<>(),new MyThreadFactory());
然后由于是要输出N次,在多线程问题中,我们需要一个支持CAS的AtomicInteger
来计数
AtomicInteger count = new AtomicInteger(1);
final int target = 10;
然后接下来就是关键了,ABC要顺序输出,也就是要实现以下流程:
计数、判断
,并且可以输出A然后细化到A/B/C三个不同的线程中,他们就分别需要做到以下功能:
说到资源,我选择了Semaphore
这个类,用资源量为1的信号量
来请求、释放资源,所以就要有了3个Semaphore
Semaphore A_B = new Semaphore(1);
Semaphore B_C = new Semaphore(1);
Semaphore C_A = new Semaphore(1);
然后就是开始运行三个线程前,对线程B/C的阻塞
A_B.acquire();
B_C.acquire();
最后就是输出部分了
executor.execute(() -> {
try {
while (true){
C_A.acquire();
System.out.print(count + ":");
System.out.print("A");
A_B.release();
}
} catch (InterruptedException ignored) {}
});
executor.execute(() -> {
try {
while (true){
A_B.acquire();
System.out.print("B");
B_C.release();
}
} catch (InterruptedException ignored) {
}
});
executor.execute(() -> {
try {
while (true){
B_C.acquire();
System.out.println("C");
if(count.getAndIncrement() >= target){
executor.shutdownNow();
}
C_A.release();
}
} catch (InterruptedException ignored) {
}
});
最终输出:
1:ABC
2:ABC
3:ABC
4:ABC
5:ABC
6:ABC
7:ABC
8:ABC
9:ABC
10:ABC
完整代码:https://github.com/zhuyst/ThreadPoolExecutor_Learn/blob/master/src/indi/zhuyst/learn/abc/Main.java