1. 程式人生 > >Java多執行緒(十二):中斷機制

Java多執行緒(十二):中斷機制

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

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

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