Java線程中的interrupt()方法

如何中斷線程?

已經拋棄的方法

  • 通過調用stop()方法停止線程,該方法有點暴力停止的意思,比如線程A去停止線程B,停止的時候根本不知道線程B的執行情況,還有就是執行stop()之後,線程B會馬上釋放鎖,可能會引發數據不同步的問題
  • 類似的被拋棄的還有suspend()和resume()方法

目前用的方法

  • 調用interrupt(),通知線程應該中斷了
    • 如果線程處於被阻塞狀態,那麼線程將立即退出被阻塞狀態,並拋出一個InterruptedException異常
    • 如果線程處於正常活動狀態,那麼會將該線程的中斷標誌設置爲true。被設置中斷標誌的線程將繼續正常運行,不受影響
  • 需要被調用的線程配合中斷
    • 在正常運行任務時,可以自行檢查本線程的中斷標誌位(Thread.currentThread().interrupt();),如果被設置了中斷標誌可以由我們自行停止線程。

測試

 public static void main(String[] args) throws InterruptedException {
            Runnable interruptTask = new Runnable() {
                @Override
                public void run() {
                    int i = 0;
                    try {
                        //在正常運行任務時,經常檢查本線程的中斷標誌位,如果被設置了中斷標誌就自行停止線程
                        while (!Thread.currentThread().isInterrupted()) {
                            Thread.sleep(100); // 休眠100ms
                            i++;
                            System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") 循環次數: " + i);
                        }
                    } catch (InterruptedException e) {
                        //在調用阻塞方法時正確處理InterruptedException異常。(例如,catch異常後就結束線程。)
                        System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") 捕獲中斷異常.");
                    }
                }
            };
            Thread t1 = new Thread(interruptTask, "t1");
            System.out.println(t1.getName() +" ("+t1.getState()+") 新建......");

            t1.start();                      // 啓動“線程t1”
            System.out.println(t1.getName() +" ("+t1.getState()+") 已啓動......");

            // 主線程休眠300ms,然後主線程給t1發“中斷”指令。
            Thread.sleep(300);
            t1.interrupt();
            System.out.println(t1.getName() +" ("+t1.getState()+") 被中斷中......");

            // 主線程休眠300ms,然後查看t1的狀態。
            Thread.sleep(300);
            System.out.println(t1.getName() +" ("+t1.getState()+") 線程終止......");
        }

// 測試結果

t1 (NEW) 新建......
t1 (RUNNABLE) 已啓動......
t1 (RUNNABLE) 循環次數: 1
t1 (RUNNABLE) 循環次數: 2
t1 (TIMED_WAITING) 被中斷中......
t1 (RUNNABLE) 捕獲中斷異常.
t1 (TERMINATED) 線程終止......

  • 這個測試便是一個簡單的中斷操作,將線程的中斷標識改爲true,我們在線程中設置了循環檢測器,一旦中斷標識被修改,則由我們自行進行停止。
  • 這裏解釋一下爲什麼會拋出異常,因爲主線程中斷300ms後去中斷線程,線程中的while極大可能在執行第四次循環,位於sleep阻塞,故要拋出異常,然後結束線程。還有一點可以說明,結果倒數第三行,線程狀態爲(TIMED_WAITING) 是限期等待,說明此時線程在執行sleep方法。

線程的六個狀態

上邊的測試裏面我們用到了getState()來獲取線程的狀態,下邊介紹一下線程的狀態:

  • 新建(New):創建後未啓動的線程的狀態

  • 運行(Runnable):包含Running和Ready,在操作系統中,它有可能正在執行也有可能正在等待cpu爲它分配執行時間

  • 無限期等待(Waiting):不會被分配CPU執行時間,需要顯示地被喚醒

    • 沒有設置Timeout參數的Object.wait()方法。
    • 沒有設置Timeout參數的Thread.join()方法。
    • LockSupport.park()方法
  • 限期等待(Timed Waiting):在一定時間後會由系統自動喚醒

    • Thread.sleep()
    • 設置Timeout參數的Object.wait()方法。
    • 設置Timeout參數的Thread.join()方法。
  • 阻塞(Blocked):等待獲取排他鎖

  • 結束(Terminated):已終止線程的狀態,線程已結束執行。終止的線程無法再次復生。

附上一張線程狀態圖

在這裏插入圖片描述

以上純爲個人理解,如有不對,請各位看官及時指出(輕噴)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章