开发者社区> 问答> 正文

[@倚贤][¥20]为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用

为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用

展开
收起
月下丶 2018-12-14 22:40:12 2778 0
2 条回答
写回答
取消 提交回答
  • 因为wait和notify本质上都要获取这个对象上的锁,所以为了防止冲突要把他放到同步块里

    2019-07-17 23:21:42
    赞同 展开评论 打赏
  • 前一个帐号wangccsy@126.com不知道怎么的就成了企业帐号,改不成个人。所以重新注册了一个个人帐号。老程序员。精通JAVA,C#,数据库,对软件开发过程和流程熟悉。考取系统分析师,项目管理师和系统架构设计师等软件资格考试认证。愿意和大家一起前进。

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

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

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

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

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

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

    2019-07-17 23:21:42
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
fibjs 模块重构从回调到协程--陈垒 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载