使用Lock和Condition完成线程的按序交替
题干:编写一个程序,开启 3 个线程,这三个线程的 ID 分别为A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要 求输出的结果必须按顺序显示。
如:ABCABCABC…… 依次递归
思路:首先要创建3个线程ABC,他们通过标志来进行切换(对应flag=1、2、3),由于要求第一个打印的是A,那么一开始flag的默认值需要为1,对应执行A线程,[A线程执行完后,将flag变成2,并且唤醒B线程],[B线程执行完后,将flag变成3,并且唤醒C线程],[C线程执行完后,将flag变成1,唤醒A线程],如果根据flag的值,让3个线程进行等待和唤醒。
代码:
package leo.conditionTest;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为
* A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要
* 求输出的结果必须按顺序显示。
* 如:ABCABCABC…… 依次递归
*/
public class ConditionTest {
static int flag = 1;
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
// A线程
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
// 判断是否轮到A
if (flag != 1) {
try {
conditionA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行A的任务:打印A
System.out.println(Thread.currentThread().getName());
// 唤醒B
flag = 2;
conditionB.signal();
}
} finally {
lock.unlock();
}
}
}, "A").start();
// B线程
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
// 判断是否轮到B
if (flag != 2) {
try {
conditionB.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行B的任务:打印B
System.out.println(Thread.currentThread().getName());
// 唤醒C
flag = 3;
conditionC.signal();
}
} finally {
lock.unlock();
}
}
}, "B").start();
// C线程
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
// 判断是否轮到c
if (flag != 3) {
try {
conditionC.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行C的任务:打印C
System.out.println(Thread.currentThread().getName());
System.out.println("---------------" + "这是第 " + (i + 1) + " 次" + "---------------");
// 唤醒A
flag = 1;
conditionA.signal();
}
} finally {
lock.unlock();
}
}
}, "C").start();
}
}
执行结果: