对于wait,notify的使用推荐看通过wait和notify来协调线程执行顺序
题目
有三个线程,分别只能打印A,B和C
要求按顺序打印ABC,打印10次
输出示例:
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
代码及其注释
//注意wait和notify的使用都要先用synchronized对相应的对象加锁
public class Demo3 {
private static Object locker1 = new Object();
private static Object locker2 = new Object();
private static Object locker3 = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
//不能确定当前是否可以打印A,要等待被唤醒才能打印
synchronized (locker1) {
locker1.wait();
}
//被唤醒后便开始打印A
System.out.print('A');
//打印A后便可以唤醒打印B的线程
synchronized (locker2) {
locker2.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
//不能确定当前是否可以打印B,要等待被唤醒才能打印
synchronized (locker2) {
locker2.wait();
}
//被唤醒后便开始打印B
System.out.print('B');
//打印B后便可以唤醒打印C的线程
synchronized (locker3) {
locker3.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
//不能确定当前是否可以打印B,要等待被唤醒才能打印
synchronized (locker3) {
locker3.wait();
}
//被唤醒后便开始打印C
System.out.println('C');
//打印C后便可以唤醒打印A的线程
synchronized (locker1) {
locker1.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
//要等待一段时间才去唤醒线程t1打印A,因为要是刚启动线程就去进行唤醒,可能这个时候线程t1都还没有调用wait方法进入阻塞等待呢
//此时调用notify方法唤醒就会落空,当线程t1调用wait方法进入阻塞等待时又没有唤醒的程序了,程序就会卡死
Thread.sleep(1000);
//首先要打印A,所以先唤醒打印A的线程
synchronized (locker1) {
locker1.notify();
}
}
}