• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:Java并发基石篇下

java 搞代码 4年前 (2022-02-19) 19次浏览 已收录 0个评论

Object wait和notify的实现机制

Java Object类提供了一个基于native实现的wait和notify线程间通信的形式,这是除了synchronized之外的另外一块独立的并发根底局部,无关wait和notify·的局部内容,咱们在下面剖析monitor的exit的时候曾经有一些波及,然而并没有过多的深刻,留下了不少的疑难,本大节会详细分析。

wait实现

ObjectMonitor类中的wait函数代码实现如下:

<code class="cpp">void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
  ...
  if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
    ...
    // 抛出异样,不会间接进入期待     THROW(vmSymbols::java_lang_InterruptedException());
    ...
  }
  ...
  ObjectWaiter node(Self);
  node.TState = ObjectWaiter::TS_WAIT;
  Self->_ParkEvent->reset();
  OrderAccess::fence();

  Thread::SpinAcquire(&_WaitSetLock, "WaitSet - add");
  AddWaiter(&node);
  Thread::SpinRelease(&_WaitSetLock);

  if ((SyncFlags & 4) == 0) {
    _Responsible = NULL;
  }

  ...
  // exit the monitor   exit(true, Self); 
  ...
  if (interruptible && (Thread::is_interrupted(THREAD, false) || HAS_PENDING_EXCEPTION)) {
        // Intentionally empty       } else if (node._notified == 0) {
        if (millis <= 0) {
          Self->_ParkEvent->park();
        } else {
          ret = Self->_ParkEvent->park(millis);
        }
  }
  // 被 notify 唤醒之后的善后逻辑   ...
}

照例只列出wait函数的外围性能局部,首先会判断一下以后线程是否为可中断并且是否曾经被中断,如果是的话会间接抛出InterruptedException异样,而不会进入wait期待,否则的话,就须要执行上面的期待过程,首先会依据Self以后线程新建一个ObjectWaiter对象节点,这个对象咱们在后面剖析monitor的enter的视乎就曾经见过了。生成一个新的节点之后就是须要将这个节点放到期待队列中,通过调用AddWaiter函数实现node的入队操作,不过在入队操作之前须要取得互斥锁以保障并发平安:

<code class="cpp">void Thread::SpinAcquire(volatile int * adr, const char * LockName) {
  if (Atomic::cmpxchg (1, adr, 0) == 0) {
    return;   // normal fast-path return   }

  // Slow-path : We've encountered contention -- Spin/Yield/Block strategy.   TEVENT(SpinAcquire - ctx);
  int ctr = 0;
  int Yields = 0;
  for (;;) {
    while (*adr != 0) {
      ++ctr;
      if ((ctr & 0xFFF) == 0 || !os::is_MP()) {
        if (Yiel<p style="color:transparent">来源gao!%daima.com搞$代*!码网</p>ds > 5) {
          os::naked_short_sleep(1);
        } else {
          os::naked_yield();
          ++Yields;
        }
      } else {
        SpinPause();
      }
    }
    if (Atomic::cmpxchg(1, adr, 0) == 0) return;
  }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:Java并发基石篇下
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址