美文网首页
java锁机制之「wait」和「notify」

java锁机制之「wait」和「notify」

作者: 乌木山 | 来源:发表于2019-11-09 19:16 被阅读0次

    关键字

    锁通信 wait notify

    我们知道java线程一共有6种状态,分别是NEWRUNABLEBLOCKEDWAITINGTIMED_WATINGTERMINATED。而线程之前的状态切换,其中一个方式就是靠wait()、notify()机制实现。
    wait/notify机制 类似一种生产者-消费者模型。 当一个线程在获取到资源的锁后,发现该资源不满足使用条件,就会调用wait()方法,等待该资源满足条件后再继续执行。 而notify()则类似生产者,如果资源满足条件了,则通过调用notify(),随机的唤醒一个之前等待的线程,通知其条件已满足,可以继续执行。

    定义

    wait() notify()是Object类中的两个本地方法。对于wait()方法,解释如下:
    我们假设一个资源为object。如果一个线程调用了资源object的wait()方法,那么将会发生如下事情:

    • 线程进入到object的等待队列(wait set),使自身由runable变为了waiting状态。
    • 释放持有的object锁。
    • 等待其他线程调用object的notify、notifyAll方法才会被再次唤醒。

    唤醒之后,线程则又变为可调度状态,然后需要同其他线程再次去竞争object资源的锁。一旦获取到锁之后,线程就会完全恢复,继续从object.wait()之后的代码开始执行。
    由于我们一般是因为不满足某些条件,才会调用wait方法等待,因此在线程恢复执行后,我们总是应该再次去check一下条件是否满足。这是因为这样,我们总是在一个循环中触发wait()方法,类似:

               synchronized (obj) {
                   while (<条件不满足>)
                       obj.wait(timeout);
                   ... // 条件已满足,开始执行相应的业务逻辑
               }
    

    notify方法则是用来从object的等待队列里,随机的唤醒一个线程。被唤醒的线程再去竞争获取object的锁,然后继续执行。

    整个运作机制可以简单用下图来表示:


    wait/notify

    说明

    无论是wait()还是notify(),其执行的前提条件都是:该线程首先持有资源对象object的锁。否则的话,就会抛出IllegalMonitorStateException异常。
    wait(long timeout):和wait()方法类似的还有一个wait(long timeout),如果线程一直没有被唤醒,当超时时间到了,就会自动被唤醒。
    notifyAll():notify()方法,也对应有一个notifyAll()方法,该方法会将等待队列里的所有线程都唤醒,唤醒后的线程行为和notify()保持一致。

    事实上一个线程被唤醒的方式包括以下几种:

    • 其他线程调用object的notify()方法, 而该线程刚好被从等待队列中选中.
    • 其他线程调用了notifyAll()方法。
    • 其他线程通过interrupt中断了该线程。
    • 等待超时时间到达,线程被自动唤醒。

    刚刚上文也提到了执行notify和wait,必须先获取到资源对象的锁,获取锁的方式有三种:

    • 执行对象的同步方法。
    • 执行对象的同步代码块。
    • 对于类对象,执行类的静态同步方法。

    参考文献

    https://www.jianshu.com/p/9ac697c166f3
    https://www.jianshu.com/p/1dafbf42cc54

    相关文章

      网友评论

          本文标题:java锁机制之「wait」和「notify」

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