1
7.1、含义(需仔细研读)
wait()、notify()是Object类的方法, 调用这2个方法前,执行线程必须已经获得改对象的对象锁,即只能在同步方法或同步代码块中调用wait() 或者notify()方法,如果调用这2个方法时没有获得对象锁将会抛出IllegalMonitorStateException异常
调用wait()方法后,当前线程立即释放已经获得的锁,并且将当前线程置入“预执行队列(WaitSet)中”, 并且在wait()所在的代码处停止执行,必须直到收到notify()方法的通知或者被中断执行当前线程才能被唤醒继续往wait()方法后面的代码执行
notitify()方法用来通知那些等待获取该对象锁的线程, 如果有多个线程等待,则由线程规划器随机挑选出一个处于wait状态的线程B,对其发出Notify通知,使B退出等待队列,处于就绪状态,被重新唤醒的线程B会尝试获取临界区的对象锁,被唤醒线程B在真正获取到锁后就会继续执行wait()后面的代码。需要说明的是,在执行notify()方法后,并不会使当前线程A马上释放对象锁,处于wait状态的线程B也不能马上获取对象锁,要等到执行notify()方法的线程A将程序执行完,也就是退出synchronized代码块后,当前线程A才会释放对象锁,但是释放之后并不代表线程B就一定会获取到对象锁,只是说此时A、B都有机会竞争获取到对象锁
如果notify()方法执行时,此时并没有任何线程处于wait状态,那么执行该方法相当于无效操作
notify()与notifyAll()的区别是:notify()方法每次调用时都只是从所有处于wait状态的线程中随机选择一个线程进入就绪状态,而notifyAll()则是使所有处于wait状态的线程全部退出等待队列,全部进入就绪状态,此处唤醒不等于所有线程都获得该对象的monitor,此时优先级最高的那个线程优先执行(获得对象锁),但也有可能是随机执行(获得对象锁),这要取决于jvm实现
7.2、生产者消费者模式
7.2.1、 版本1产生假死(全部进入等待wait状态)
package chapter2;
import java.util.stream.Stream;
/**
-
@author calebzhao<9 3 9 3 4 7 5 0 7 @ qq.com>
-
2019/6/30 7:44
*/
public class ProducerAndConsumerVersion1 {private final Object LOCK = new Object();
private boolean isProduced;
private int num = 0;
public static void main(String[] args) {
ProducerAndConsumerVersion1 version1 = new ProducerAndConsumerVersion1();
Stream.of("P1", "P2", "P3", "P4").forEach((item) ->{
new Thread(() ->{
while (true) {
version1.produce();
}}, item).start(); }); Stream.of("C1").forEach(item ->{ new Thread(() ->{ while (true) { version1.consumer(); } }, item).start(); }); System.out.println("主线程执行结束");}
public void produce(){
synchronized (LOCK){
if (isProduced){
try {
System.out.println("[" + Thread.currentThread().getName() +"] produce wait");
LOCK.wait();System.out.println("[" + Thread.currentThread().getName() +"] produce wait after"); } catch (InterruptedException e) { e.printStackTrace(); } } else { num++; System.out.println("[" + Thread.currentThread().getName() + "] P ==>" + num); isProduced=true; LOCK.notify(); System.out.println("[" + Thread.currentThread().getName() + "] notify after"); } }}
public void consumer(){
synchronized (LOCK){if (isProduced){ System.out.println("[" + Thread.currentThread().getName() + "] C ==>" + num); isProduced = false; LOCK.notify(); System.out.println("[" + Thread.currentThread().getName() + "] notify after"); } else { try { System.out.println("[" + Thread.currentThread().getName() +"] consumer wait"); LOCK.wait(); System.out.println("[" + Thread.currentThread().getName() +"] consumer wait after"); } catch (InterruptedException e) { e.printStackTrace(); } } }}
}

浙公网安备 33010602011771号