➜ jdk hg id 76072a077ee1+ jdk-11+28
首先看下Thread.interrupt方法
Java类 java.lang.Thread
public void interrupt() {
if (this != Thread.currentThread()) {
checkAccess();
// thread may be blocked in an I/O operation
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // set interrupt status
b.interrupt(this);
return;
}
}
}
// set interrupt status
interrupt0();
}
...
private native void interrupt0();
该方法主要做了两件事,首先是调用interrupt0,转向JVM做进一步的中断处理,其次是调用blocker.interrupt方法,中断blocker的当前操作,比如堵塞的io读写等。
我们这里主要看下interrupt0方法。该方法是native方法,看下对应的JVM内部的代码
文件 src/hotspot/share/prims/jvm.cpp
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
...
if (is_alive) {
// jthread refers to a live JavaThread.
Thread::interrupt(receiver);
}
JVM_END
该方法最终调用了Thread::interrupt方法,看下这个方法
文件 src/hotspot/share/runtime/thread.cpp
void Thread::interrupt(Thread* thread) {
...
os::interrupt(thread);
}
该方法调用了os::interrupt方法,继续看下这个
文件 src/hotspot/os/posix/os_posix.cpp
void os::interrupt(Thread* thread) {
...
OSThread* osthread = thread->osthread();
if (!osthread->interrupted()) {
osthread->set_interrupted(true);
...
ParkEvent * const slp = thread->_SleepEvent ;
if (slp != NULL) slp->unpark() ;
}
// For JSR166. Unpark even if interrupt status already was set
if (thread->is_Java_thread())
((JavaThread*)thread)->parker()->unpark();
ParkEvent * ev = thread->_ParkEvent ;
if (ev != NULL) ev->unpark() ;
}
这个方法就是最终的interrupt实现,它会首先设置线程的interrupted状态为true,然后分别调用各种ParkEvent或Parker的unpark方法,使其从阻塞状态返回。
比如,上面的_SleepEvent就是对应Thread.sleep方法,((JavaThread*)thread)->parker()就是对应LockSupport.park方法,_ParkEvent就是对应synchronized同步块及Object.wait方法。
有关ParkEvent或Parker的unpark方法是如何实现的,请看其他文章: