场景描述
线程ABC交替执行,A执行完B执行,B执行完C执行,C执行完A执行。
算法
Lock的多条件变量
public class Main {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition first = lock.newCondition();
Condition second = lock.newCondition();
Condition third = lock.newCondition();
MyThread thread1 = new MyThread(first, second, "第一个线程", lock);
MyThread thread2 = new MyThread(second, third, "第二个线程", lock);
MyThread thread3 = new MyThread(third, first, "第三个线程", lock);
new Thread(thread1).start();
new Thread(thread2).start();
new Thread(thread3).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
lock.lock();
first.signal();
} finally {
lock.unlock();
}
}
}
class MyThread implements Runnable {
private Condition condition;
private Condition nextCondition;
private String threadName;
private ReentrantLock lock;
public MyThread(Condition condition, Condition nextCondition, String threadName, ReentrantLock lock) {
this.condition = condition;
this.nextCondition = nextCondition;
this.threadName = threadName;
this.lock = lock;
}
@Override
public void run() {
int num = 0;
while (num < 5) {
if (lock.tryLock()) {
try {
try {
Thread.sleep(1000);
condition.await();
System.out.println(threadName + " 运行第 " + (num + 1) + " 次");
num++;
nextCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
}
}
}
park
public class Main {
public static void main(String[] args) {
Runner runner1 = new Runner(5, null);
Thread t1 = new Thread(runner1, "t1");
Runner runner2 = new Runner(5, null);
Thread t2 = new Thread(runner2, "t2");
Runner runner3 = new Runner(5, null);
Thread t3 = new Thread(runner3, "t3");
// 这里不能一开始就注入 nextThread 属性,因为一开始都是空,需要先初始化后手动注入
runner1.setNextThread(t2);
runner2.setNextThread(t3);
runner3.setNextThread(t1);
t1.start();
t2.start();
t3.start();
try {
Thread.sleep(1000);
LockSupport.unpark(t1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Runner implements Runnable {
private int loopNum;
private Thread nextThread;
public Runner(int loopNum, Thread nextThread) {
this.loopNum = loopNum;
this.nextThread = nextThread;
}
public void setNextThread(Thread nextThread) {
this.nextThread = nextThread;
}
@Override
public void run() {
int index = 0;
while (index < loopNum) {
try {
// 休眠任意整数秒
Thread.sleep(1000L *(int)(Math.random()*10));
} catch (InterruptedException e) {
e.printStackTrace();
}
LockSupport.park();
System.out.println(Thread.currentThread().getName() + " 运行了 " + ++index + "次");
LockSupport.unpark(nextThread);
}
}
}