Thread.interrupt()源码跟踪

1 JDK源码跟踪

// java.lang.Thread
public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();           // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

private native void interrupt0();

2 OpenJDK源码跟踪

  • jdk源码(JNI注册)
// jdk/src/share/native/java/lang/Thread.c:43
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},
};

// jdk/src/share/javavm/export/jvm.h:254
JNIEXPORT void JNICALL
JVM_Interrupt(JNIEnv *env, jobject thread);
  • java虚拟机(HotSpot实现):
// hotspot/src/share/prims/jvm.cpp:3289
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_Interrupt");

  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
  // We need to re-resolve the java_thread, since a GC might have happened during the
  // acquire of the lock
  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
  if (thr != NULL) {
    Thread::interrupt(thr);
  }
JVM_END

// hotspot/src/share/vm/runtime/thraed.cpp:634
ParkEvent * _ParkEvent ;   // for synchronized()
ParkEvent * _SleepEvent ; // for Thread.sleep
ParkEvent * _MutexEvent ; // for native internal Mutex/Monitor,互斥锁
ParkEvent * _MuxEvent ;   // for low-level muxAcquire-muxRelease,共享锁

// hotspot/src/share/vm/runtime/thraed.cpp:804
void Thread::interrupt(Thread* thread) {
  trace("interrupt", thread);
  debug_only(check_for_dangling_thread_pointer(thread);)
  os::interrupt(thread);
}

// hotspot/src/hotspot/os/linux/vm/os_linux.cpp:4192
void os::interrupt(Thread* thread) {
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
    "possibility of dangling Thread pointer");

  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 ;
    // Thread.sleep方法继续运行
    if (slp != NULL) slp->unpark() ;
  }

  // For JSR166. Unpark event if interrupt status already was set
  if (thread->is_Java_thread())
    ((JavaThread*)thread)->parker()->unpark();

  ParkEvent * ev = thread->_ParkEvent ;
  if (ev != NULL) ev->unpark() ;
}

// hotspot/src/share/vm/runtime/osThread.hpp:很短自己看
volatile jint _interrupted; // Thread.isInterrupted state    

volatile bool interrupted() const{
    return _interrupted != 0;
}

void set_interrupted(bool z){
    _interrupted = z ? 1 : 0;
}

原文地址:https://www.cnblogs.com/linzhanfly/p/11258496.html

时间: 2024-10-06 10:13:48

Thread.interrupt()源码跟踪的相关文章

Thread类源码剖析

目录 1.引子 2.JVM线程状态 3.Thread常用方法 4.拓展点 一.引子 说来也有些汗颜,搞了几年java,忽然发现竟然没拜读过java.lang.Thread类源码,这次特地拿出来晒一晒.本文将剖析Thread类源码(本文后面源码全部默认JDK8),并讲解一些重要的拓展点.希望对大家能有一些帮助. 本文讲解主干全部出自源码和注释,保证了权威性.(注意:网上,某些书中很多观点都是错的,过时的,片面的,所以大家一定要看源码,重要事情说N遍,看源码!看源码!看源码......) 二.JVM

LayoutInflater效率分析及源码跟踪

一.效率分析 测试设备 测试设配:魅族MX4 操作系统:Android5.1操作系统 CPU型号:联发科MT6595 内存: 2GB 测试方法 使用LayoutInflater对3组不同复杂度的xml布局进行解析,每次解析100次,测试10次,求其100次的平均运行时间.单位为ms. 测试结果 | | Xml文件 |Time(ms/100)| |---------------|-----------------------|------------| |第一组(简单) |深度2节点4 属性30个

1 weekend110的hdfs源码跟踪之打开输入流 + hdfs源码跟踪之打开输入流总结

3种形式的元数据,fsimage是在磁盘上,meta.data是在内存上, 我们继续,前面呢,断点是打在这一行代码处, FileSystem fs = FileSystem.get(conf); weekend110的hdfs下载数据源码跟踪铺垫  +  hdfs下载数据源码分析-getFileSystem 现在,开始weekend110的hdfs源码跟踪之打开输入流 1.  清掉之前,所有的断点, dfs是fs的成员, 此刻,断点过不去了,为什么?因为,这需要在服务器上运行. 由此可见,new

Java源码跟踪阅读技巧

转:https://www.jianshu.com/p/ab865109070c 本文基于Eclipse IDE 1.Quick Type Hierarchy 快速查看类继承体系. 快捷键:Ctrl + T Quick Type Hierarchy.png 查看类很多人可能都知道,可源码阅读的时候更多用来查看方法体系更重要,可以方便快速的定位到方法的实现类.如: getBean.png 此时如果想查看getBean()方法如何实现,可能会让你失望.结果如下: image.png 进入到了Bean

谁动了我的截图?--Monkeyrunner takeSnapshot方法源码跟踪分析

本文章的目的是通过分析monkeyrunner是如何实现截屏来作为一个例子尝试投石问路为下一篇文章做准备,往下一篇文章本人有意分析下monkeyrunner究竟是如何和目标测试机器通信的,所以最好的办法本人认为是先跟踪一个调用示例从高层到底层进行分析,本人以前分析操作系统源代码的时候就是先从用户层的write这个api入手,然后一路打通到vfs文件系统层,到设备驱动层的,其效果比单纯的理论描述更容易理解和接受. 在整个代码分析过程中会设计到以下的库,希望想动手分析的同学们准备好源码: monke

CAS 单点登出失效的问题(源码跟踪)

一.环境说明 服务端:cas-server-3.5.2 客户端:cas-client-3.2.1+spring mvc 说明:服务端与客户端均是走的Https 客户端配置文件: applicationContext-cas.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xm

.spring jdbctemplate源码跟踪

闲着没事,看看源码也是一种乐趣! java操作数据库的基本步骤都是类似的: 1. 建立数据库连接 2. 创建Connection 3. 创建statement或者preparedStateement 4. 执行sql,返回ResultSet 5. 关闭resultSet 5.关闭statement 6.关闭Connection Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. 1. 构造函数,三种

Hibernate 5.x 生成 SessionFactory 源码跟踪分析

我们要使用 Hibernate 的功能,首先需要读取 Hibernate 的配置文件,根据配置启动 Hibernate ,然后创建 SessionFactory. 创建 SessionFactory 的代码很简单,这也是我们要分析的代码: Configuration cfg = new Configuration().configure(); SessionFactory factory = cfg.buildSessionFactory(); 接下来,就针对这两行代码进行分析. 1.初始化 C

Spring源码跟踪之ContextLoaderListener

首先我们来看一段web.xml中的配置: <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframewor