一個關於ExecutorService shutdownNow時很奇怪的現象


我們知道很多類庫中的阻塞方法在拋出InterruptedException后會清除線程的中斷狀態(例如 sleep、 阻塞隊列的take),但是今天卻發現了一個特別奇怪的現象,先給出代碼:

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }
                
                System.out.println(Thread.currentThread().isInterrupted());
                
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });
        
        executor.shutdownNow();
    }

 如果按照我的理解,調用shutdownNow后會給線程池中的工作者線程發出中斷請求,並在第一個睡眠的地方拋出 InterruptedException ,但是在拋出異常后這種中斷狀態就應該被清除了,所以第二次睡眠不應該失敗,但是結果卻是失敗的,本來以為是系統的原因,可是在linux下測試也是如此。

更令人不解的是如果我把第二次睡眠換成其他的阻塞方法(queue.take)那么就不會拋出異常,而是正常阻塞。 

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        final BlockingQueue<String> queue = new LinkedBlockingQueue<>();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }
                
                System.out.println(Thread.currentThread().isInterrupted());
                
                try {
                    queue.take();
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });
        
        executor.shutdownNow();
    }

 還有更讓人受不了的,如果我們在任務最開始隨便寫點什么,就會按照我們期待的執行了(心中一萬只草泥馬呀)

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("xxxx");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("first interrupted!!!");
                }
                
                System.out.println(Thread.currentThread().isInterrupted());
                
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    System.out.println("second interrupted!!!");
                }
            }
        });
        
        executor.shutdownNow();
    }

 

以后有機會再研究吧,可能還是知識不夠吧!!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM