park/unpark操作
这两个操作通常配合在一起使用,park操作用于阻塞当前线程,unpark用于使阻塞在park操作代码处的线程退出阻塞。
unpark操作
该方法是一个native方法:
public native void unpark(Object thread); |
该方法实现unsafe.cpp在\hotspot\src\share\vm\prims目录下。
UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) UnsafeWrapper("Unsafe_Unpark"); Parker* p = NULL; if (jthread != NULL) { oop java_thread = JNIHandles::resolve_non_null(jthread); if (java_thread != NULL) { jlong lp = java_lang_Thread::park_event(java_thread); if (lp != 0) { // This cast is OK even though the jlong might have been read // non-atomically on 32bit systems, since there, one word will // always be zero anyway and the value set is always the same p = (Parker*)addr_from_java(lp); } else { // Grab lock if apparently null or using older version of library MutexLocker mu(Threads_lock); java_thread = JNIHandles::resolve_non_null(jthread); if (java_thread != NULL) { JavaThread* thr = java_lang_Thread::thread(java_thread); if (thr != NULL) { p = thr->parker(); if (p != NULL) { // Bind to Java thread for next time. java_lang_Thread::set_park_event(java_thread, addr_to_java(p)); } } } } } } if (p != NULL) { #ifndef USDT2 HS_DTRACE_PROBE1(hotspot, thread__unpark, p); #else /* USDT2 */ HOTSPOT_THREAD_UNPARK( (uintptr_t) p); #endif /* USDT2 */ p->unpark(); } UNSAFE_END |
以上代码需要展开来才能看得懂,展开后代码如下:
如果定义了USDT2宏
extern "C" { void JNICALL Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread) { JavaThread* thread=JavaThread::thread_from_jni_environment(env); ThreadInVMfromNative __tiv(thread);
/* do nothing */
HandleMarkCleaner __hm(thread); Thread* THREAD = thread;
/* begin of body */
/*nothing, for the present*/;
Parker* p = NULL; if (jthread != NULL) { oop java_thread = JNIHandles::resolve_non_null(jthread); if (java_thread != NULL) { jlong lp = java_lang_Thread::park_event(java_thread); if (lp != 0) { // This cast is OK even though the jlong might have been read // non-atomically on 32bit systems, since there, one word will // always be zero anyway and the value set is always the same p = (Parker*)addr_from_java(lp); } else { // Grab lock if apparently null or using older version of library MutexLocker mu(Threads_lock); java_thread = JNIHandles::resolve_non_null(jthread); if (java_thread != NULL) { JavaThread* thr = java_lang_Thread::thread(java_thread); if (thr != NULL) { p = thr->parker(); if (p != NULL) { // Bind to Java thread for next time. java_lang_Thread::set_park_event(java_thread, addr_to_java(p)); } } } } } } if (p != NULL) { ; p->unpark(); } } } |
如果没有定义USDT2宏
这里不展开USDT2宏没有定义的那段代码 |
其中主要的代码在:
p->unpark(); |
这块代码实现在os_solaris.cpp,在\hotspot\src\os\solaris\vm目录下。
void Parker::unpark() { int s, status ; status = os::Solaris::mutex_lock (_mutex) ; assert (status == 0, "invariant") ; s = _counter; _counter = 1; status = os::Solaris::mutex_unlock (_mutex) ; assert (status == 0, "invariant") ;
if (s < 1) { status = os::Solaris::cond_signal (_cond) ; assert (status == 0, "invariant") ; } } |