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();
             }
         }
     }
    

    }

}

posted @ 2019-11-30 19:47  CalebZhao  阅读(114)  评论(0)    收藏  举报