实现思路:
三个线程基于不同的Condition
完成等待和继续
最简单的实现(不考虑任何封装):
public class Solution {
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("1");
try {
lock.lock();
condition2.signal();
condition1.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}).start();
//线程start之后不一定立即run起来-这里测试用的代码-用来先后启动目标线程
Thread.sleep(100);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("2");
try {
lock.lock();
condition3.signal();
condition2.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}).start();
//线程start之后不一定立即run起来-这里测试用的代码-用来先后启动目标线程
Thread.sleep(100);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("3");
try {
lock.lock();
condition1.signal();
condition3.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}).start();
}
}
简单封装一下
public class Solution {
private static class PrintRunnable implements Runnable {
private final String value;
private final Lock lock;
private final Condition cur, next;
public PrintRunnable(String value, Lock lock, Condition cur, Condition next) {
this.value = value;
this.lock = lock;
this.cur = cur;
this.next = next;
}
@Override
public void run() {
while (true) {
System.out.println(value);
try {
lock.lock();
//这里
next.signal();
//这里特别注意:await会阻塞线程-因此要在这之前触发signal
cur.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
new Thread(new PrintRunnable("1", lock, condition1, condition2)).start();
Thread.sleep(100);
new Thread(new PrintRunnable("2", lock, condition2, condition3)).start();
Thread.sleep(100);
new Thread(new PrintRunnable("3", lock, condition3, condition1)).start();
}
}