- 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
如:ABCABCABC…… 依次递归
在上一章节中,我们学习了 锁 Lock 以及对应的 condition 线程通讯的控制。那么通过一个锁 Lock 可以创建多个 condition ,例如:
然后我们只要在实现线程类的时候,做好阻塞和唤醒的次序即可。如下:
好了,下面来实现一下代码。
import jdk.nashorn.internal.ir.CallNode;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,
* 每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
* <p>
* 如:ABCABCABC…… 依次递归
*
* @author Aron.li
* @date 2020/11/3 23:02
*/
public class TestABCAlternate {
public static void main(String[] args) {
AlternateDemo ad = new AlternateDemo();
//创建线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ad.runThreadA();
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ad.runThreadB();
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
ad.runThreadC();
}
}
}, "C").start();
}
}
class AlternateDemo {
//成员属性
private int number = 1; //标记当前执行的线程
//创建lock
private ReentrantLock lock = new ReentrantLock();
//创建三个线程的 Condition
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
//设置后续线程中,执行的方法
public void runThreadA() {
//如果当前是线程1,则 调用 condition1.await() 阻塞 线程1,
// 然后调用 condition2.signal() 唤醒 线程2
lock.lock();//创建锁
try {
//1.判断当前不为线程1,则阻塞线程1
if (number != 1) {
condition1.await();
}
//2.打印A
System.out.print(Thread.currentThread().getName());
//3.唤醒线程2
number = 2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁
}
}
public void runThreadB() {
//如果当前是线程2,则 调用 condition2.await() 阻塞 线程2,
// 然后调用 condition3.signal() 唤醒 线程3
lock.lock();//创建锁
try {
//1.判断当前不为线程2,则阻塞线程2
if (number != 2) {
condition2.await();
}
//2.打印B
System.out.print(Thread.currentThread().getName());
//3.唤醒线程3
number = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁
}
}
public void runThreadC() {
//如果当前是线程3,则 调用 condition3.await() 阻塞 线程3,
// 然后调用 condition1.signal() 唤醒 线程1
lock.lock();//创建锁
try {
//1.判断当前不为线程3,则阻塞线程3
if (number != 3) {
condition3.await();
}
//2.打印C
System.out.print(Thread.currentThread().getName());
//3.唤醒线程1
number = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁
}
}
}
执行效果如下:
image-20201103233658677