线程运行顺序控制¶
固定运行顺序¶
先让线程2执行,然后线程1再执行
wait+notify¶
public class Test1 {
private static final Object lock = new Object();
// 表示 t2 是否运行过
private static boolean t2Runned = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() ->{
// 如果 t2 没有运行过, 需要等待
synchronized (lock){
while (!t2Runned){
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
log.info("1");
}, "t1");
Thread t2 = new Thread(() ->{
synchronized (lock){
log.info("2");
// 运行结束之后通知其他线程
t2Runned = true;
lock.notify();
}
}, "t2");
log.info("t1 开始运行");
t1.start();
Thread.sleep(1000L);
t2.start();
}
}
await+signal¶
public class Test2 {
private static ReentrantLock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
// 表示 t2 是否运行过
private static boolean t2Runned = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() ->{
lock.lock();
try{
while (!t2Runned){
condition.await();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
log.info("1");
}, "t1");
Thread t2 = new Thread(() ->{
lock.lock();
try{
log.info("2");
// 运行结束之后通知其他线程
t2Runned = true;
condition.signal();
} finally {
lock.unlock();
}
}, "t2");
log.info("t1 开始运行");
t1.start();
Thread.sleep(1000L);
t2.start();
}
}
交替输出¶
交替打印A、B、C
wait+notify¶
使用一个标记,1打印A,2打印B,3打印C
输出内容 等待标记 下一个标记
A 1 2
B 2 3
C 3 1
public class Test3 {
public static void main(String[] args) {
WaitNotify waitNotify = new WaitNotify(1, 100);
Thread t1 = new Thread(() -> {
waitNotify.print("A", 1, 2);
}, "t1");
Thread t2 = new Thread(() -> {
waitNotify.print("B", 2, 3);
}, "t2");
Thread t3 = new Thread(() -> {
waitNotify.print("C", 3, 1);
}, "t3");
t1.start();
t2.start();
t3.start();
}
}
class WaitNotify{
private int flag;// 等待标记
private int loopNumber;// 循环次数
public WaitNotify(int flag, int loopNumber) {
this.flag = flag;
this.loopNumber = loopNumber;
}
public void print(String str, int waitFlag, int nextFlag) {
for (int i = 0; i < loopNumber; i++) {
synchronized (this){
while (flag != waitFlag){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print(str);
flag = nextFlag;
// 唤醒其他线程
this.notifyAll();
}
}
}
}
await+signal¶
public class Test4 {
public static void main(String[] args) throws InterruptedException {
AwaitSignal awaitSignal = new AwaitSignal(10);
Condition a = awaitSignal.newCondition();
Condition b = awaitSignal.newCondition();
Condition c = awaitSignal.newCondition();
new Thread(() -> {
awaitSignal.print("A", a, b);
}, "t1").start();
new Thread(() -> {
awaitSignal.print("B", b, c);
}, "t2").start();
new Thread(() -> {
awaitSignal.print("C", c, a);
}, "t3").start();
// 需要主线程唤醒 a
Thread.sleep(1000);
awaitSignal.lock();
try {
System.out.println("开始执行...");
a.signal();
}
finally {
awaitSignal.unlock();
}
}
}
class AwaitSignal extends ReentrantLock{
private int loopNumber;
public AwaitSignal(int loopNumber) {
this.loopNumber = loopNumber;
}
/**
* 交替打印
* @param str 需要打印的字符
* @param cur 需要进那间休息室
* @param next 打印完通知的休息室
*/
public void print(String str, Condition cur, Condition next){
for (int i = 0; i < loopNumber; i++) {
lock();
try {
// 都先等待, 直到被唤醒
cur.await();
// 开始干活
System.out.print(str);
// 通知下一个休息室
next.signal();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
unlock();
}
}
}
}