­

Java多线程(十二):中断机制

  • 2019 年 10 月 3 日
  • 筆記

这里详细分析interrupt(),interrupted(),isInterrupted()三个方法

interrupt()

中断这个线程,设置中断标识位

    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();      }

我们来找下如何设置中断标识位的
找到interrupt0()的源码,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);      ...    }      ...  }

isInterrupted()

测试线程是否被中断,线程的中断状态不会改变

public boolean isInterrupted() {          return isInterrupted(false);      }

查看native isInterrupted(boolean ClearInterrupted)源码,查找方式同上
src/hotspot/os/posix/os_posix.cpp

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();      // 清除标识位后再设置false    if (interrupted && clear_interrupted) {      osthread->set_interrupted(false);    }      return interrupted;  }

Java传递ClearInterrupted为false,对应C++的clear_interrupted

interrupted()

测试线程是否被中断,清除中断标识位

    public static boolean interrupted() {          return currentThread().isInterrupted(true);      }

简单的例子

public class MyThread45 {      public static void main(String[] args) throws Exception      {          Runnable runnable = new Runnable()          {              public void run()              {                  while (true)                  {                      if (Thread.currentThread().isInterrupted())                      {                          System.out.println("线程被中断了");                          return ;                      }                      else                      {                          System.out.println("线程没有被中断");                      }                  }              }          };          Thread t = new Thread(runnable);          t.start();          Thread.sleep(500);          t.interrupt();          System.out.println("线程中断了,程序到这里了");      }  }

检查线程是否中断,中断线程,运行结果如下

······  线程没有被中断  线程没有被中断  线程没有被中断  线程被中断了  线程中断了,程序到这里了