Synchronized解读

单独使用synchronized关键字或者配合使用wait()/notify()/notifyAll()方法,关键靠对象头Mark Word的monitor锁对象,锁对象中的_EntryList 字段存放处于等待锁block状态的线程,_WaitSet用于存放因为调用了锁对象的wait()方法而处于wait状态的线程,当调用锁对象的notify()方法时,从_WaitSet中选出一个线程进入_EntryList,等待获取锁

  • wait()方法
    wait是要释放对象锁,进入等待池。
    既然是释放对象锁,那么肯定是先要获得锁。
    所以wait必须要写在synchronized代码块中,否则会报异常。

  • notify()方法
    也需要写在synchronized代码块中,
    调用对象的这两个方法也需要先获得该对象的锁.
    notify,notifyAll, 唤醒等待该对象同步锁的线程,并放入该对象的锁池中.
    对象的锁池中线程可以去竞争得到对象锁,然后开始执行.

  • 如果是通过notify来唤起的线程,那进入wait的线程会被随机唤醒;(这个要看具体的虚拟机的实现,hotspot默认情况将_WaitSet中的第一个元素进行出队操作,
    这也说明了notify是个顺序操作, 具有公平性。原来hotspot对notofy()的实现并不是我们以为的随机唤醒, 而是“先进先出”的顺序唤醒!)

  • 如果是通过notifyAll唤起的线程,默认情况是最后进入的会先被唤起来,即LIFO的策略;

比较重要的是:
notify()或者notifyAll()调用时并不会真正释放对象锁, 必须等到synchronized方法或者语法块执行完才真正释放锁.

https://blog.csdn.net/qq_42764468/article/details/106603249

https://www.jianshu.com/p/32e1361817f0

https://www.cnblogs.com/shyroke/category/1139071.html
https://tech.meituan.com/2018/11/15/java-lock.html

https://mp.weixin.qq.com/s/oR8IDlpA01aq8byGf02_6w
https://mp.weixin.qq.com/s?__biz=MzU1NTkwODE4Mw==&mid=2247497021&idx=1&sn=a4c9e9af10ea9dbc4e6295ceb6e986a0&chksm=fbcf9805ccb81113bc2e7835645e6249bed9abe6bb96fb0eb511f0fe8dfdd67fa983503f4d0b&scene=21#wechat_redirect

notify:https://www.jianshu.com/p/ffc0c755fd8d

posted @ 2021-08-19 19:29  guardWei  阅读(53)  评论(0编辑  收藏  举报