zoukankan      html  css  js  c++  java
  • java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?

    wait()
    作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止。条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法。进入wait()方法后,当前线程释放锁。在从wait()返回前,线程与其他线程竞争重新获得锁。如果调用wait()时,没有持有适当的锁,则抛出IllegalMonitorStateException

    notify()
    作用:唤醒其他休眠的线程中的一个,这个线程由系统确定。在调用前,线程也必须要获得该对象的对象级别锁,的如果调用notify()时没有持有适当的锁,也会抛出IllegalMonitorStateException


    先回答问题:

    (1)为什么wait()必须在同步(Synchronized)方法/代码块中调用?

    答:调用wait()就是释放锁,释放锁的前提是必须要先获得锁,先获得锁才能释放锁。

    (2)为什么notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?

    答:notify(),notifyAll()是将锁交给含有wait()方法的线程,让其继续执行下去,如果自身没有锁,怎么叫把锁交给其他线程呢;(本质是让处于入口队列的线程竞争锁)

    下面是正文(详细解释):

    之前一直谨记老师教的wait(),notify(),notifyAll()必须要在Synchronized关键中使用,不得其解,现在研究了一下,终于明白了。

    首先,要明白,每个对象都可以被认为是一个"监视器monitor",这个监视器由三部分组成(一个独占锁,一个入口队列,一个等待队列)(ps:和AQS的state,同步队列,等待队列好相似)。注意是一个对象只能有一个独占锁,但是任意线程线程都可以拥有这个独占锁。

    对于对象的非同步方法而言,任意时刻可以有任意个线程调用该方法。(即普通方法同一时刻可以有多个线程调用)

    对于对象的同步方法而言,只有拥有这个对象的独占锁才能调用这个同步方法。如果这个独占锁被其他线程占用,那么另外一个调用该同步方法的线程就会处于阻塞状态,此线程进入入口队列。

    若一个拥有该独占锁的线程调用该对象同步方法的wait()方法,则该线程会释放独占锁,并加入对象的等待队列;(为什么使用wait()?希望某个变量被设置之后再执行,notify()通知变量已经被设置。)

    某个线程调用notify(),notifyAll()方法是将等待队列的线程转移到入口队列,然后让他们竞争锁,所以这个调用线程本身必须拥有锁。

    Synchronized应用举例:生产者消费者模型

    消费者线程需要等待直到生产者线程完成一次写入操作。生产者线程需要等待消费者线程完成一次读取操作。假设没有应用Synchronized关键字,当消费者线程执行wait操作的同时,生产线线程执行notify,生产者线程可能在等待队列中找不到消费者线程。导致消费者线程一直处于阻塞状态。那么这个模型就要失败了。所以必须要加Synchronized关键字。

    下面这个图是线程的状态图,没有太大关系,可以不看

    终于理解了这个图为什么sleep不释放锁,wait释放锁

    https://blog.csdn.net/qq_42145871/article/details/81950949

    https://blog.csdn.net/qbz_96/article/details/44461645

  • 相关阅读:
    What is the difference between Serialization and Marshaling?
    IEEE Standard 754 for Binary Floating-Point Arithmetic
    没有单元测试,就很难有真正的积累。
    一般只用 20% 的代码就可以解决 80% 的问题。但要想解决剩下 20% 的问题的话,则需要额外 80% 的代码。
    为失败设计,大量引入对SRE的理解,鲁棒性高
    用git合并分支时,如何保持某些文件不被合并
    git 分支合并时如何忽略某个文件
    Golang拼接字符串的5种方法及其效率_Chrispink-CSDN博客_golang 字符串拼接效率 https://blog.csdn.net/m0_37422289/article/details/103362740
    Lua大量字符串拼接方式效率对比及原因分析
    干货 | 携程多语言平台-Shark系统的高可用演进之路
  • 原文地址:https://www.cnblogs.com/twoheads/p/10678748.html
Copyright © 2011-2022 走看看