簡體   English   中英

thread.interrupt()如何設置標志?

[英]how does thread.interrupt() sets the flag?

文檔:

中斷狀態標志

The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag. By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.

我讀了這些SO帖子。 但是我認為我沒有正確理解這一點。 所以我在下面的示例代碼上對此進行了測試。 我有兩個threads正在運行。 一個是main Thread-0 ,另一個是t Thread-0

我在run方法中調用t.interrupt()Thread.currentThread().isInterrupted() 標志的確切位置在哪里? Thread Class是否維護當前正在運行的所有Threadsstatic list ,並且通過調用Thread.currentThread()獲取currentThread對象並檢查其是否被中斷? 如果Thread類本身的boolean標志interrupted ,那么如何區分兩個線程; 示例mainThread-0在這里。 兩個Threadsstatic flag相同? 步驟的確切順序是什么, set flaglook up和未unset flag在哪里等?

當我uncomment下面的code塊(當前已ommented out )時,該程序永不停止。 我不理解為什么?

import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;

    public class ThreadInterrupt {

        public static void main(String[] args) throws InterruptedException {

            System.out.println("Starting.");

            Thread t  = new Thread(new Runnable(){

                @Override
                public void run() {
                    Random ran = new Random();

                    for (int i = 0; i < 1E8; i++) {

                        /*try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            System.out.println("we have been interrupted");
                            e.printStackTrace();
                        }*/

                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("Interrupted!");
                            break;
                    }

                    Math.sin(ran.nextDouble());
        }
            }
        });
        t.start();

        Thread.sleep(500);
        t.interrupt();
        t.join();

        System.out.println("Finished.");
    }

}

當我取消注釋下面的代碼塊(當前已被注釋掉)時,該程序永不停止。 我不理解為什么?

注意Thread#interrupt()的javadoc

如果在調用 Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法時阻塞了此線程sleep(long)或sleep(long,int)此類的方法, 則其中斷狀態將被清除,並將收到InterruptedException。

因此,如果您取消注釋代碼,該標志將被取消並且您的if永遠不會執行。

線程類是否通過調用Thread.currentThread()來維護當前正在運行的所有線程的靜態列表。

Thread.currentThread()方法聲明為(Oracle JDK 7)

public static native Thread currentThread();

換句話說,它是本地實現的,可能是用C代碼實現的。 給定javadoc,我們可以假設在某個地方存儲了對所有線程的引用。 返回當前正在執行的一個。

同樣, Thread#isInterrupted()方法調用

private native boolean isInterrupted(boolean ClearInterrupted);

這也是本地實現的。 但是我們可以假設它使用了一些布爾樣式的標志。

標志的確切位置在哪里?

JVM Thread對象跟蹤該標志。

線程類是否維護當前正在運行的所有線程的靜態列表,並且通過調用Thread.currentThread()來獲取currentThread對象並檢查其是否被中斷?

Thread 不做,但是JVM做。 Thread.currentThread()是一個靜態方法,該方法返回與調用線程關聯的Thread對象。

如果Thread類本身的boolean標志被中斷,那么如何區分兩個線程? 示例main和Thread-0在這里

它是一個實例字段, 而不是靜態字段。 它是每個Thread實例。

當我取消注釋下面的代碼塊(當前已被注釋掉)時,該程序永不停止。 我不理解為什么?

因為當您中斷線程時, Thread.sleep(...)會拋出InterruptedException ,該異常會清除線程的中斷標志。 一旦捕獲InterruptedException應該始終重新中斷線程。

try {
     Thread.sleep(100);
} catch (InterruptedException e) {
     // _always_ reinterrupt the thread when you catch InterruptedException
     Thread.currentThread().interrupt();
     System.out.println("we have been interrupted");
     e.printStackTrace();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM