多线程交替顺序执行
2019-12-19 本文已影响0人
Juntech
多线程交替顺序执行
1.知识补充
1.1Condition 控制线程通信
Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用Object.wait 访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个Lock 可能与多个Condition 对象关联。为了避免兼容性问题,Condition 方法的名称与对应的Object 版本中的不同。
.在Condition 对象中,与wait、notify 和notifyAll 方法对应的分别是await、signal 和signalAll。
.Condition 实例实质上被绑定到一个锁上。要为特定Lock 实例获得Condition 实例,请使用其newCondition() 方法。
1.2面试题
编写一个程序,开启3 个线程,这三个线程的ID 分别为A、B、C,每个线程将自己的ID 在屏幕上打印10 遍,要求输出的结果必须按顺序显示。
如:ABCABCABC…… 依次递归
1.3解决方法
在这里,我们需要使用到上面的condition对进程进行控制,使其交替顺序执行
2.代码实现
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author juntech
* @version ${version}
* @date 2019/12/19 16:03
* @ClassName 类名
* @Descripe 描述
*/
public class TestABCAlternateDemo {
public static void main(String[] args) {
ABCAlterNate ad = new ABCAlterNate();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 20; i++) {
ad.loopA(i);
}
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 20; i++) {
ad.loopB(i);
}
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i < 20; i++) {
ad.loopC(i);
System.out.println("----------------------------");
}
}
}, "C").start();
}
}
class ABCAlterNate {
private int num = 1; //正在执行的标志
private Lock lock = new ReentrantLock();
//开启3个condition通信
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
/**
* @param totalLoop 循环次数
*/
public void loopB(int totalLoop) {
//加锁
lock.lock();
try {
//1.判断
if (num != 2) {
conditionB.await();
}
//2.循环打印
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
//3.唤醒
num = 3;
conditionC.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void loopC(int totalLoop) {
//加锁
lock.lock();
try {
//1.判断
if (num != 3) {
conditionC.await();
}
//2.循环打印
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
//3.唤醒
num = 1;
conditionA.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void loopA(int totalLoop) {
//加锁
lock.lock();
try {
//1.判断
if (num != 1) {
conditionA.await();
}
//2.循环打印
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
//3.唤醒
num = 2;
conditionB.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
运行,控制台输出:
A 0 1
A 1 1
A 2 1
A 3 1
A 4 1
B 0 1
B 1 1
B 2 1
B 3 1
B 4 1
C 0 1
C 1 1
C 2 1
C 3 1
C 4 1
C 5 1
C 6 1
C 7 1
C 8 1
C 9 1
C 10 1
C 11 1
C 12 1
C 13 1
C 14 1
C 15 1
C 16 1
C 17 1
C 18 1
C 19 1
----------------------------
A 0 2
A 1 2
A 2 2
A 3 2
A 4 2
B 0 2
B 1 2
B 2 2
B 3 2
B 4 2
C 0 2
C 1 2
C 2 2
C 3 2
C 4 2
C 5 2
C 6 2
C 7 2
C 8 2
C 9 2
C 10 2
C 11 2
C 12 2
C 13 2
C 14 2
C 15 2
C 16 2
C 17 2
C 18 2
C 19 2
----------------------------
A 0 3
A 1 3
A 2 3
A 3 3
A 4 3
B 0 3
B 1 3
B 2 3
B 3 3
B 4 3
C 0 3
C 1 3
C 2 3
C 3 3
C 4 3
C 5 3
C 6 3
C 7 3
C 8 3
C 9 3
C 10 3
C 11 3
C 12 3
C 13 3
C 14 3
C 15 3
C 16 3
C 17 3
C 18 3
C 19 3
----------------------------
A 0 4
.....
3.致谢
感谢各位coder抽出宝贵的时间来观看这篇文章!更多详情请访问:juntech