从OpenJdk分析Object,wait(),notify(),notifyAll()

我们知道多线程争抢临界资源,首先先进入entryList队列,然后去争抢实例对象对应的监视器的锁,例如下图ObjectMonitor结构。

waitSet是监视器上等待的线程集合。自己获得锁之后调用wait()方法。

EntryList是阻塞线程集合。ObjectWaiter是链表结构。

 

(1)wait源码解析

void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {

   Thread * const Self = THREAD ;// 将当前线程赋值给Selft

   /*************/

ObjectWaiter node(Self); //将当前线程转化为ObjectWaiter
Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ;//先自旋
AddWaiter (&node) ;//线程加入waitSet队列
Thread::SpinRelease (&_WaitSetLock) ;
_waiters++;                  // increment the number of waiters
 _recursions = 0;             // set the recursion level to be 1
exit (true, Self) ;                    // exit the monitor

 

(2)notify源码解析

void ObjectMonitor::notify(TRAPS) {

  CHECK_OWNER();

  if (_WaitSet == NULL) {  //若waitSet为空,直接返回

     TEVENT (Empty-Notify) ;

     return ;

  }

ObjectWaiter * iterator = DequeueWaiter() ;

  if (iterator != NULL) {

    if (Policy == 0) {   

     /*******/

     } else if( Policy == 1){

/*******/

 

}

}

结合Object的notify javaDoc,我们知道若一个线程在等待,那么他们中的一个将被唤醒,选择策略在实现上是任意的。在源码中对应各种Policy

 

(3)notifyAll源码解析

       nofifyAll会唤醒ObjectWaiter列表所有对象

void ObjectMonitor::notifyAll(TRAPS) {

   ObjectWaiter* iterator;

   if (_WaitSet == NULL) {

      TEVENT (Empty-NotifyAll) ;

      return ;

  }

  for (;;) { //for循环唤醒所有的waitSet中的ObjectWaiter

  

 

(4)synchronized锁

  从Jdk1.6开始, synchronized锁d的实现发生了很大变化,jvm引入了相应的优化手段提升性能。这种提升涉及到偏向锁,轻量级锁,重量级锁等从而避免锁的竞争带来的用户态和内核态的切换。锁的优化是由java对象头的中的标志位来实现的,锁的访问与改变都和java对象头息息相关。

  从jdk1.6之后,对象实例在堆中化分3个组成部分:对象头,实例数据,对齐填充。对象头组要有3块组成:(1)Mark word (2)指向类的指针(3)数组长度

  Mark word它记录了对象,锁以及垃圾回收相关信息,(1)无锁标记(2)偏向锁(3)轻量级锁(4)重量级锁(5)GC标记。

  锁的演化由经历: 无锁 ==>偏向锁 ==>轻量级锁 ==>重量级锁

  锁的升级是根据偏向锁标志位是否和Mark Word中锁标志位一致来达成的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值