您的位置:首页 > 教育 > 培训 > java的Unsafe类native方法unpark park在底层jvm中实现原理

java的Unsafe类native方法unpark park在底层jvm中实现原理

2024/10/5 17:15:57 来源:https://blog.csdn.net/u014200244/article/details/140547872  浏览:    关键词:java的Unsafe类native方法unpark park在底层jvm中实现原理

java的Unsafe类native方法unpark park在底层jvm中实现原理

public native void unpark(Object thread);
public native void park(boolean isAbsolute, long time);

jvm源码

Unsafe_Unpark

UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) {Parker* p = NULL;if (jthread != NULL) {ThreadsListHandle tlh;JavaThread* thr = NULL;oop java_thread = NULL;(void) tlh.cv_internal_thread_to_JavaThread(jthread, &thr, &java_thread);if (java_thread != NULL) {// This is a valid oop.if (thr != NULL) {// The JavaThread is alive.p = thr->parker();}}} // ThreadsListHandle is destroyed here.// 'p' points to type-stable-memory if non-NULL. If the target// thread terminates before we get here the new user of this// Parker will get a 'spurious' unpark - which is perfectly valid.if (p != NULL) {HOTSPOT_THREAD_UNPARK((uintptr_t) p);p->unpark();}
} UNSAFE_ENDvoid Parker::unpark() {int status = pthread_mutex_lock(_mutex);assert_status(status == 0, status, "invariant");const int s = _counter;_counter = 1;// must capture correct index before unlockingint index = _cur_index;status = pthread_mutex_unlock(_mutex);assert_status(status == 0, status, "invariant");// Note that we signal() *after* dropping the lock for "immortal" Events.// This is safe and avoids a common class of futile wakeups.  In rare// circumstances this can cause a thread to return prematurely from// cond_{timed}wait() but the spurious wakeup is benign and the victim// will simply re-test the condition and re-park itself.// This provides particular benefit if the underlying platform does not// provide wait morphing.if (s < 1 && index != -1) {// thread is definitely parkedstatus = pthread_cond_signal(&_cond[index]);assert_status(status == 0, status, "invariant");}
}

Unsafe_Park

UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) {HOTSPOT_THREAD_PARK_BEGIN((uintptr_t) thread->parker(), (int) isAbsolute, time);EventThreadPark event;JavaThreadParkedState jtps(thread, time != 0);thread->parker()->park(isAbsolute != 0, time);if (event.should_commit()) {const oop obj = thread->current_park_blocker();if (time == 0) {post_thread_park_event(&event, obj, min_jlong, min_jlong);} else {if (isAbsolute != 0) {post_thread_park_event(&event, obj, min_jlong, time);} else {post_thread_park_event(&event, obj, time, min_jlong);}}}HOTSPOT_THREAD_PARK_END((uintptr_t) thread->parker());
} UNSAFE_ENDvoid Parker::park(bool isAbsolute, jlong time) {// Optional fast-path check:// Return immediately if a permit is available.// We depend on Atomic::xchg() having full barrier semantics// since we are doing a lock-free update to _counter.if (Atomic::xchg(0, &_counter) > 0) return;Thread* thread = Thread::current();assert(thread->is_Java_thread(), "Must be JavaThread");JavaThread *jt = (JavaThread *)thread;// Optional optimization -- avoid state transitions if there's// an interrupt pending.if (Thread::is_interrupted(thread, false)) {return;}// Next, demultiplex/decode time argumentsstruct timespec absTime;if (time < 0 || (isAbsolute && time == 0)) { // don't wait at allreturn;}if (time > 0) {to_abstime(&absTime, time, isAbsolute);}// Enter safepoint region// Beware of deadlocks such as 6317397.// The per-thread Parker:: mutex is a classic leaf-lock.// In particular a thread must never block on the Threads_lock while// holding the Parker:: mutex.  If safepoints are pending both the// the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.ThreadBlockInVM tbivm(jt);// Don't wait if cannot get lock since interference arises from// unparking. Also re-check interrupt before trying wait.if (Thread::is_interrupted(thread, false) ||pthread_mutex_trylock(_mutex) != 0) {return;}int status;if (_counter > 0)  { // no wait needed_counter = 0;status = pthread_mutex_unlock(_mutex);assert_status(status == 0, status, "invariant");// Paranoia to ensure our locked and lock-free paths interact// correctly with each other and Java-level accesses.OrderAccess::fence();return;}OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);jt->set_suspend_equivalent();// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()assert(_cur_index == -1, "invariant");if (time == 0) {_cur_index = REL_INDEX; // arbitrary choice when not timedstatus = pthread_cond_wait(&_cond[_cur_index], _mutex);assert_status(status == 0 MACOS_ONLY(|| status == ETIMEDOUT),status, "cond_wait");}else {_cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;status = pthread_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);assert_status(status == 0 || status == ETIMEDOUT,status, "cond_timedwait");}_cur_index = -1;_counter = 0;status = pthread_mutex_unlock(_mutex);assert_status(status == 0, status, "invariant");// Paranoia to ensure our locked and lock-free paths interact// correctly with each other and Java-level accesses.OrderAccess::fence();// If externally suspended while waiting, re-suspendif (jt->handle_special_suspend_equivalent_condition()) {jt->java_suspend_self();}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com