9.线程按序交替
线程按序交替
- 编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C,每个线程将自己的 ID 在屏幕上打印 10 遍,要求输出的结果必须按顺序显示。
如:ABCABCABC…… 依次递归
解决的思路
在上一章节中,我们学习了 锁 Lock 以及对应的 condition 线程通讯的控制。那么通过一个锁 Lock 可以创建多个 condition ,例如:
-
线程1 使用 condition1 来控制阻塞、唤醒 -
线程2 使用 condition2 来控制阻塞、唤醒 -
线程3 使用 condition3 来控制阻塞、唤醒
然后我们只要在实现线程类的时候,做好阻塞和唤醒的次序即可。如下:
-
如果当前是线程1,则 调用 condition1.await() 阻塞 线程1,然后调用 condition2.signal() 唤醒 线程2 -
如果当前是线程2,则 调用 condition2.await() 阻塞 线程2,然后调用 condition3.signal() 唤醒 线程3 -
如果当前是线程3,则 调用 condition3.await() 阻塞 线程3,然后调用 condition1.signal() 唤醒 线程1
好了,下面来实现一下代码。
实现代码
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(); // 释放锁
}
}
}
执行效果如下:
原文始发于微信公众号(海洋的渔夫):9.线程按序交替
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/34950.html