介绍
最近看看多线程练习题,练习下多线程,这道题:ABC三个线程如何保证顺序执行。三个线程同时启动,然后按照顺序执行,每个线程执行10次。
思路
首先想到了等待队列Condition唤醒部分线程,使用ReentrantLock进行加锁。
初始版实现
/**
* @description A\B\C三个线程顺序执行10次
*
* @author sunpy
* @date 2018年11月28日 下午2:23:45
*/
public class MyTest {
static class MyTask {
private static ReentrantLock rl = new ReentrantLock();
private static Condition conditionA = rl.newCondition();
private static Condition conditionB = rl.newCondition();
private static Condition conditionC = rl.newCondition();
private static int number = 0;
public void execute() {
rl.lock();
try {
while (number < 30) {
if (number % 3 == 0) {
System.out.println(Thread.currentThread().getName() + " - " + number);
number++;
conditionB.signal();
conditionA.await();
}
if (number % 3 == 1) {
System.out.println(Thread.currentThread().getName() + " - " + number);
number++;
conditionC.signal();
conditionB.await();
}
if (number % 3 == 2) {
System.out.println(Thread.currentThread().getName() + " - " + number);
number++;
conditionA.signal();
conditionC.await();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rl.unlock();
}
}
}
public static void main(String[] args) {
final MyTask myTask = new MyTask();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute();
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute();
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute();
}
}, "C").start();
}
}
说明:通过余数判断来执行,需要循环30次,有点不合理。想了下,执行10次,循环10次,但是让线程按照ABC执行就可以了。根据这个想法写出了改进版。
改进版实现
/**
* @description A\B\C三个线程顺序执行10次
*
* @author sunpy
* @date 2018年11月28日 下午2:23:45
*/
public class MyTest {
static class MyTask {
private static ReentrantLock rl = new ReentrantLock();
private static Condition conditionA = rl.newCondition();
private static Condition conditionB = rl.newCondition();
private static Condition conditionC = rl.newCondition();
public void execute(String flag) {
rl.lock();
try {
for (int i = 1 ; i <= 10 ; i++) {
if ("A".equals(flag)) {
System.out.println(Thread.currentThread().getName() + " - " + i);
conditionB.signal();
conditionA.await();
}
if ("B".equals(flag)) {
System.out.println(Thread.currentThread().getName() + " - " + i);
conditionC.signal();
conditionB.await();
}
if ("C".equals(flag)) {
System.out.println(Thread.currentThread().getName() + " - " + i);
conditionA.signal();
conditionC.await();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
rl.unlock();
}
}
}
public static void main(String[] args) {
final MyTask myTask = new MyTask();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute("A");
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute("B");
}
}, "B").start();
new Thread(new Runnable() {
@Override
public void run() {
myTask.execute("C");
}
}, "C").start();
}
}
网友评论