(一)線程管理_4---線程休眠和恢復

線程休眠和恢復

在有的時候須要將線程暫時中止執行,在一段時間後恢復線程,讓其繼續執行;好比一個線程每隔一分鐘執行一次狀態檢查,那麼餘下的時間咱們但願它可以讓出CPU time,什麼也不作,最大的減小資源的浪費;在線程恢復後,再給予CPU time,讓其繼續執行;爲了知足這樣一個需求,能夠調用Thread類的sleep()方法達到這個目的;java

Thread.sleep(millis) ,另外還可使用TimeUnit類進行休眠,如TimeUnit.SECONDS.sleep(millis) ;ide

動手實驗

public class FileClock implements Runnable{
    @Override
    public void run() {
        /*
            每次循環打印一個時間,模擬一個任務,以後休眠1毫秒,
            在sleep時,若是被中斷,將會拋出InterruptedException
         */
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s\n",new Date());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.out.printf("The FileClock has been interrupted.");
            }
        }
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new FileClock());
        thread.start();

        /*
            主線程等待5毫秒
         */
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*
            喚醒FileClock線程
         */
        thread.interrupt();
    }
}

一次運行結果:spa

Thu Oct 30 23:09:25 CST 2014
Thu Oct 30 23:09:26 CST 2014
Thu Oct 30 23:09:27 CST 2014
Thu Oct 30 23:09:28 CST 2014
Thu Oct 30 23:09:29 CST 2014
The FileClock has been interrupted.Thu Oct 30 23:09:30 CST 2014
Thu Oct 30 23:09:31 CST 2014
Thu Oct 30 23:09:32 CST 2014
Thu Oct 30 23:09:33 CST 2014
Thu Oct 30 23:09:34 CST 2014
線程


首先,fileclock線程開始執行,而後主線程等待,在fileclock還沒結束,主線程執行對fileclock執行了interrupt()方法,注意這裏,上節記錄的這個方法會有effect以及它和IsInterrupt的區別,這個方法設置線程的中斷標記,那麼此時有一個問題:若是此時fileclock剛尚未進入sleep方法,此時該怎麼執行?會不會當再次進入sleep時直接中斷進入catch塊,仍是執行休眠完後中斷? 若是此時fileclock線程正在休眠,顯然會直接中斷被catch塊捕獲,這個就毫無疑問了,那麼下面就上面這個疑惑進行一個實驗,主線程啓動子線程後,調用interrupt,設置子線程已經中斷,故意讓子線程必定在主線程執行了interrupt以後,子線程才調用sleep,已觀察執行過程,那麼下面開始debug

public class InterruptTest implements Runnable{
    @Override
    public void run() {
        /*
            while的目的是保證在主線執行完thread.interrupt()方法後,才結束while
            執行下面的sleep,能夠經過結果的兩個輸出看出(Before,After)
         */
        long start=System.currentTimeMillis();
        while((System.currentTimeMillis()-start)<5000){
            //empty
        }
        System.out.printf("After:Thread will be sleep.\n");
        try {
            TimeUnit.SECONDS.sleep(200);
            System.out.printf("After sleep.\n");
        } catch (InterruptedException e) {
            System.out.printf("Interrupted.");
        }
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new InterruptTest());
        thread.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        thread.interrupt();
        System.out.printf("Before:Main execute thread.interrupt().\n");
    }
}
執行結果:

Before:Main execute thread.interrupt().
After:Thread will be sleep.
Interrupted.
code

顯然 sleep語句後面的「After sleep"並無輸出,從輸出的結果能夠看到子線程也並無去休眠200毫秒,而至直接中斷被catch捕獲;資源

那麼能夠得出結論:當一個線程的被設置了中斷狀態,如調用了interrupt(),那麼該線程在執行到sleep時,將會當即被中斷捕獲;it


要點

仍是要理解線程維護的中斷狀態和Thread.interrupt()以後線程如何執行;io

此外 Thread.yield()方法也能是線程暫時放棄cpu,可是JVM並不保證線程的這個請求的響應;一般,僅僅是做爲debug的目的;class

相關文章
相關標籤/搜索