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("執行緒中斷了,程式到這裡了");      }  }

檢查執行緒是否中斷,中斷執行緒,運行結果如下

······  執行緒沒有被中斷  執行緒沒有被中斷  執行緒沒有被中斷  執行緒被中斷了  執行緒中斷了,程式到這裡了