012.多線程-interrupt線程的中斷

版權聲明:本文爲博主原創文章,允許轉載,請標明出處。

interrupt()

中斷線程, 具體使用場景可以查看下面的源碼以及註釋

    /**
     * 中斷線程
     *
     * 除非當前線程中斷自身,
     * 否則在checkAccess中將會拋出SecurityException
     *
     * 如果當前線程在 wait、join、sleep 中被阻塞,
     * 將會清除它的中斷狀態(isInterrupted() is false),
     * 並拋出InterruptedException
     *
     * 如果當前線程在java.nio.channels上的I/O操作被阻塞,
     * 則通道將被關閉,線程的中斷狀態被設置(isInterrupted() is true),
     * 並拋出ClosedByInterruptException
     *
     * 如果當前線程在java.nio.channels.Selector中被阻塞,
     * 則線程的中斷狀態被設置(isInterrupted() is true),
     * 並立即返回,可能帶有非零值。
     * 類似於調用了java.nio.channels.Selector的wakeup方法
     *
     * 如果上面的條件都不存在,
     * 則線程的中斷狀態被設置(isInterrupted() is true)
     *
     */
    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();
    }

isInterrupted()

    /**
     * 測試這個線程是否被中斷,
     * 但是線程的中斷狀態,不受此方法的影響
     *
     * 當一個線程死亡的時候,
     * 設置線程的中斷狀態將會被忽略,
     * 調用此方法將返回false
     *
     * 如果這個線程被中斷(即:中斷狀態被設置)
     * 則返回true,否則,返回false。
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

interrupted()

    /**
     * 測試當前線程是否中斷
     * 返回結果與isInterrupted返回值一樣,
     * 
     * 但該方法會清除線程的中斷狀態
     * 
     * 即:不過當前線程狀態如何,如果連續調用兩次此方法,
     * 則,第二次調用將返回false。
     * 因爲,第一次調用時已清除了中斷狀態。
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

code of demo:

package cn.qbz.thread;

import org.springframework.validation.annotation.Validated;

/**
 * @Author: 花生米
 * @Date: 2018/11/16 10:20
 */
public class InterruptTest {

    public static void main(String[] args) throws InterruptedException {
        Test2 test2 = new Test2();
        System.out.println("\n線程未啓動之前:" + test2.isInterrupted());
        test2.start();
        System.out.println("\n調用interrupt前:" + test2.isInterrupted());

        test2.interrupt();
        System.out.println("\n調用interrupt,中斷狀態被設置:" + test2.isInterrupted());

        while (true) {
            if (test2.isAlive()) {
                Thread.sleep(2000);
            } else {
                break;
            }
        }
        System.out.println("\n線程已死亡:" + test2.isInterrupted());
    }

}

class Test2 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 600001; i++) {
            System.out.print("");

            if (i == 600000) {
                System.out.println("interrupted:" + Thread.interrupted());
                System.out.println("interrupted late::" + isInterrupted());
            }
        }
        System.out.println("線程即將死亡...");
        
        interrupt();
        System.out.println("interrupted late::" + isInterrupted());
    }

}

注意事項:

interrupted 測試的時當前線程; isInterrupted 測試的時被調用的線程。

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