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; } }