美文网首页
Object.wait() Object.notify

Object.wait() Object.notify

作者: 我是许仙 | 来源:发表于2020-08-19 16:40 被阅读0次
    前提 - wait()为什么在Object中
    • Java中每一个对象都可以成为一个监视器(Monitor), 该Monitor由一个锁(lock), 一个等待队列(waiting queue) , 一个入口队列(entry queue)组成。
    • 对于一个对象的方法, 如果没有synchronized关键字修饰, 该方法可以被任意数量的线程,在任意时刻调用。
      对于添加了synchronized关键字的方法,任意时刻只能被唯一的一个获得了对象实例锁的线程调用。
    • synchronized用于实现多线程的同步操作

    所以获取到对象锁的线程才能执行wait()方法。

    Object.wait() 使用

    这个方法导致当前线程等待,直到其他的线程调用这个对象的Object.notify方法或者Object.notifyAll()方法。

    当前线程必有拥有这个对象的监视器(获得锁).并且当前线程把自己放到Object对象的等待列队中,并释放Object的所有的同步声明。

    wait() Object.notify

    一个线程修改了一个值之后另一个线程感知到线程的变化。我们可以通过wait()来阻塞一个线程,然后通过业务条件来进行切换从而实现生产者消费者模型。

    调用Object.wait() Object.notify 为什么加锁呢?
     public static Object lock = new Object();
    
        public static boolean flag = true;
    
        public static void main(String[] args) {
          //Thread1  
          new Thread(() -> {
                try {
                    //1
                    if (flag) {
                        //4
                        lock.wait();
                    }
                    TimeUnit.SECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "thread1").run();
    
          //Thread2
            new Thread(() -> {
                System.out.println("释放");
                //2
                flag = false;
                //3
                lock.notify();
            }, "thread2").run();
            
        }
    

    如果不加锁的话,在多线程环境按照1234步骤执行,会造成先Thread2.notify()而 Thread1.wait()线程一直处于等待状态无法释放。

    原理

    wait(), notify(), notifyAll()synchronized 需要搭配使用, 用于线程同步wait()总是在一个循环中被调用,挂起当前线程来等待一个条件的成立。 Wait调用会一直等到其他线程调用notifyAll()时才返回。当一个线程在执行synchronized的方法内部,调用了wait()后, 该线程会释放该对象的锁, 然后该线程会被添加到该对象的等待队列中(waiting queue), 只要该线程在等待队列中, 就会一直处于阻塞状态,不会被调度执行。 要注意wait()方法会强迫线程先进行释放锁操作,所以在调用wait()时, 该线程必须已经获得锁,否则会抛出异常。但是由于wait()synchronized的方法内部被执行, 锁一定已经获得, 就不会抛出异常了。

    当一个线程调用一个对象的notify()方法时, 调度器会从所有处于该对象等待队列(waiting queue)的线程中取出任意一个线程, 将其添加到入口队列(entry queue)中. 然后在入口队列中的多个线程就会竞争对象的锁, 得到锁的线程就可以继续执行。 如果等待队列中(waiting queue)没有线程, notify()方法不会产生任何作用.notifyAll()notify()工作机制一样, 区别在于notifyAll()会将等待队列(waiting queue)中所有的线程都添加到入口队列中(entry queue).otifyAll()notify()更加常用, 因为notify()方法只会唤起一个线程,且无法指定唤醒哪一个线程.

    相关文章

      网友评论

          本文标题:Object.wait() Object.notify

          本文链接:https://www.haomeiwen.com/subject/wjhdjktx.html