等待通知是一个经典的范式,该范式分为两部分,分别是针对等待方(消费者)和通知方(生产者)。
等待方遵循如下原则:
1)获取对象的锁
2)如果条件不满足,调用wait方法,被通知后仍要检查条件
3)条件满足执行对应逻辑
伪代码如下:
synchronized(对象){
while(条件不满足){
对象.wait();
}
执行对应逻辑;
}
通知方遵循如下原则:
1)获取对象的锁
2)改变条件
3)通知所有等待在对象上的线程
伪代码如下:
synchronized(对象){
改变条件;
对象.notifyAll();
}
分析了范式,接下来就来小试牛刀一番吧
如题:两个线程交替打印数字(1-26)和字母(A-Z)。
定义线程A打印数字,线程B打印字母。针对这个题,两个线程都即使等待方也是通知方,需要结合上述等待方和通知方
话不多说,上代码,自行对应以上原则
public class ThreadPrint {
private static final Object lock = new Object();//对象锁
private static boolean flag = false;//判断条件,false-线程A打印,true-线程B打印
public static void main(String[] args) {
Thread threadA = new Thread(() -> {
for (int i = 1; i < 27; i++) {
synchronized (lock) {
while (flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
flag = true;
lock.notifyAll();
}
}
});
Thread threadB = new Thread(() -> {
for (char i = 'A'; i <= 'Z'; i++) {
synchronized (lock) {
while (!flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
flag = false;
lock.notifyAll();
}
}
});
threadA.start();
threadB.start();
}
}