某公司面试题?线程的控制是使用线程必须掌握的.
问题:需要A,B,C使用三个不同的线程执行,但是他们的顺序不能乱,如ABC
并依次循环执行多次,可以控制A,B或C的执行次数.
实现代码如下:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author 嘿嘿嘿1212
* @version 1.0
* @date 2020/2/1 21:44
*/
public class TestABCAlternate {
public static void main(String[] args) {
AlternateDemo ad = new AlternateDemo();
//A线程
new Thread(() -> {
for (int i = 0; i < 20; i++) {
ad.loopA(i);
}
}, "A").start();
//B线程
new Thread(() -> {
for (int i = 0; i < 20; i++) {
ad.loopB(i);
}
}, "B").start();
//C线程
new Thread(() -> {
for (int i = 0; i < 20; i++) {
ad.loopC(i);
}
}, "C").start();
}
}
class AlternateDemo {
//当前线程正在执行的线程的标记
private int number = 1;
private Lock lock = new ReentrantLock();
//创建控制不同线程的Condition
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void loopA(int totalLoop) {
lock.lock();
try {
while (number != 1) {
condition1.await();
}
for (int i = 1; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
number = 2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void loopB(int totalLoop) {
lock.lock();
try {
while (number != 2) {
condition2.await();
}
for (int i = 1; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
number = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void loopC(int totalLoop) {
lock.lock();
try {
while (number != 3) {
condition3.await();
}
for (int i = 1; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
}
System.out.println("------------------------------------------------------");
number = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
解析:
- 该代码是通过在不同线程执行时,判断当前线程是否是应该执行的线程,如不是则进行等待.
- 当被标记的线程执行完毕后,修改标记,并唤醒另一应执行线程.
condition.await()方法会释放当前线程持有的锁
- 线程唤醒构成循环,则会到达执行一轮后,开始执行下一轮
- 而多轮循环的实现是在线程中构成循环(调用一次方法则只会执行一次),而执行第二次方法时,该线程会根据标记是否应该执行.