##java层 native代码
private native boolean isInterrupted(boolean ClearInterrupted);
private native void interrupt0();
##Thread.c代码
注册函数
static JNINativeMethod methods[] = {{"start0", "()V", (void *)&JVM_StartThread},{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},{"suspend0", "()V", (void *)&JVM_SuspendThread},{"resume0", "()V", (void *)&JVM_ResumeThread},{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},{"yield", "()V", (void *)&JVM_Yield},{"sleep", "(J)V", (void *)&JVM_Sleep},{"currentThread", "()" THD, (void *)&JVM_CurrentThread},{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},{"interrupt0", "()V", (void *)&JVM_Interrupt},{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};JNIEXPORT void JNICALL
Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
##jvm 层C++代码 jvm.cpp代码
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))JVMWrapper("JVM_Interrupt");ThreadsListHandle tlh(thread);JavaThread* receiver = NULL;bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);if (is_alive) {// jthread refers to a live JavaThread.Thread::interrupt(receiver);}
JVM_ENDJVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))JVMWrapper("JVM_IsInterrupted");ThreadsListHandle tlh(thread);JavaThread* receiver = NULL;bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);if (is_alive) {// jthread refers to a live JavaThread.return (jboolean) Thread::is_interrupted(receiver, clear_interrupted != 0);} else {return JNI_FALSE;}
JVM_END
##thread.cpp代码
void Thread::interrupt(Thread* thread) {debug_only(check_for_dangling_thread_pointer(thread);)os::interrupt(thread);
}bool Thread::is_interrupted(Thread* thread, bool clear_interrupted) {debug_only(check_for_dangling_thread_pointer(thread);)// Note: If clear_interrupted==false, this simply fetches and// returns the value of the field osthread()->interrupted().return os::is_interrupted(thread, clear_interrupted);
}
##os_posix.cpp代码。中断unpark唤醒线程
void os::interrupt(Thread* thread) {debug_only(Thread::check_for_dangling_thread_pointer(thread);)OSThread* osthread = thread->osthread();if (!osthread->interrupted()) {osthread->set_interrupted(true);// More than one thread can get here with the same value of osthread,// resulting in multiple notifications. We do, however, want the store// to interrupted() to be visible to other threads before we execute unpark().OrderAccess::fence();ParkEvent * const slp = thread->_SleepEvent ;if (slp != NULL) slp->unpark() ;}// For JSR166. Unpark even if interrupt status already was setif (thread->is_Java_thread())((JavaThread*)thread)->parker()->unpark();ParkEvent * ev = thread->_ParkEvent ;if (ev != NULL) ev->unpark() ;
}bool os::is_interrupted(Thread* thread, bool clear_interrupted) {debug_only(Thread::check_for_dangling_thread_pointer(thread);)OSThread* osthread = thread->osthread();bool interrupted = osthread->interrupted();// NOTE that since there is no "lock" around the interrupt and// is_interrupted operations, there is the possibility that the// interrupted flag (in osThread) will be "false" but that the// low-level events will be in the signaled state. This is// intentional. The effect of this is that Object.wait() and// LockSupport.park() will appear to have a spurious wakeup, which// is allowed and not harmful, and the possibility is so rare that// it is not worth the added complexity to add yet another lock.// For the sleep event an explicit reset is performed on entry// to os::sleep, so there is no early return. It has also been// recommended not to put the interrupted flag into the "event"// structure because it hides the issue.if (interrupted && clear_interrupted) {osthread->set_interrupted(false);// consider thread->_SleepEvent->reset() ... optional optimization}return interrupted;
}