2013-08-07 59 views
3

我正在讀線程的sleep()方法。我試圖開發一個小例子。關於這個例子我有兩個 混淆。如何把一個特定的線程睡覺()?

/** 
* Created with IntelliJ IDEA. 
* User: Ben 
* Date: 8/7/13 
* Time: 2:48 PM 
* To change this template use File | Settings | File Templates. 
*/ 

class SleepRunnable implements Runnable{ 

    public void run() { 
    for(int i =0 ; i < 100 ; i++){ 
     System.out.println("Running: " + Thread.currentThread().getName()); 
    } 
    try { 
     Thread.sleep(500); 
    } 
    catch(InterruptedException e) { 
     System.out.println(Thread.currentThread().getName() +" I have been interrupted"); 
    } 
    } 
} 

public class ThreadSleepTest { 
    public static void main(String[] args){ 
    Runnable runnable = new SleepRunnable(); 
    Thread t1 = new Thread(runnable); 
    Thread t2 = new Thread(runnable); 
    Thread t3 = new Thread(runnable); 
    t1.setName("Ben"); 
    t2.setName("Rish"); 
    t3.setName("Mom"); 
    t1.start(); 
    t2.start(); 
    t3.start(); 
    } 
} 
  1. 正如我在去年的帖子討論,會如果一個線程在指定的時間量後醒來發生中斷例外,它會簡單地從run方法返回。在這個例子中,代碼永遠不會進入catch()塊。爲什麼這樣?
  2. 現在,上面例子中的所有線程都會睡一會兒,並且會優雅地輪流,如果我特別想讓線程「Ben」睡眠,該怎麼辦。在這個例子中我不這麼認爲。

有人可以進一步闡述這個概念。

+1

你永遠不會中斷您的任何線程 - 沒有爲什麼睡覺會拋出異常... – assylias

回答

4

正如我在去年的帖子討論,會如果 線程在指定的時間後醒來,併發生中斷異常它會簡單地從run方法 回報。在我的這個例子中,代碼從不 進入catch()塊。爲什麼這樣?

您不會在代碼中的任何地方撥打interrupt()。現在

t1.interrupt(); //this will throw the exception when t1 is sleeping 

,所有在上面的例子中的線程會睡第二 ,並會輪流擺好,如果你對我特別想讓 線程「奔」的睡眠。我不認爲在這個 的例子中是可能的。

的線程不輪流在這個例子中是精確的,他們不知道關於彼此獨立工作。

提示: 檢查當前線程和睡眠的名稱,如果名稱是Ben

Thread.currentThread().getName() //for getting the name of the current thread 

編輯:

再現中斷:增加睡眠時間間隔爲10000毫秒

主要方法代碼:

Thread t1 = new Thread(runnable); 
Thread t2 = new Thread(runnable); 
Thread t3 = new Thread(runnable); 
t1.setName("Ben"); 
t2.setName("Rish"); 
t3.setName("Mom"); 
t1.start(); 
t2.start(); 
t3.start(); 

Thread.sleep(1000); //make the main thread to sleep for a sec 

//time to interrupt t1 !!!! 
t1.interrupt(); //throws Interrupted exception in the run method of Thread t1 
+0

那麼這是否意味着我現在的例子並沒有讓任何線程進入睡眠狀態? – benz

+0

是的,它讓睡眠的線程。只需將睡眠間隔的值增加到10000毫秒即可。你會看到效果。 –

+0

非常感謝。我現在看到了效果。它等待時間。 – benz

2

1)不正確,如果線程在指定的超時後喚醒,則不會發生InterruptedException,線程將簡單地恢復運行。您的代碼不進入catch塊,因爲它一直沒有中斷,如果你想看到InterruptedException的從T3試試這個

... 
t3.start(); 
t3.interrupt(); 
... 

2)我覺得你可以做這樣的事情

... 
if (Thread.currentThread().getName().equals("Ben")) { 
    try { 
     Thread.sleep(500); 
    } 
    ... 

} 
6

1.當timout達不成InterruptedException被拋出。當你中斷當前正在睡覺的線程時它會被拋出。

在活動之前或活動期間,線程正在等待,休眠或以其他方式佔用以及線程中斷時拋出。偶爾一個方法可能希望測試當前線程是否被中斷,如果是,立即拋出這個異常。以下代碼可用於實現此效果: if(Thread.interrupted())//清除中斷狀態! throw new InterruptedException();

2.執行代碼只能使睡眠成爲當前線程。因此,您可以通過名稱確定您的線程,例如:

if ("Ben".equals(Thread.currentThread().getName())) { 
try { 
    Thread.sleep(500); 
} catch (InterruptedException e) {} 
} 
+0

謝謝噸塔拉。我理解了這個概念,我想我的例子中沒有任何線程在睡覺。 – benz

+2

在你的例子中,每個線程都在睡眠0.5秒。如果你添加了我提出的'if',那麼只有Ben會睡覺0.5秒 – Tala

+0

非常感謝Tala – benz

0

InterruptedException只會在運行系統必須喚醒進程時纔會發生。 通過sleep()使線程進入睡眠狀態將使其跳過處理器的線程隊列。如果它由於某種原因需要關注,那麼它將觸發一個InterruptedException InterruptedException也可能發生,當它正在運行時,處理器必須在線程的時間片用完之前將控制權從線程中除去,主要是因爲有更高的piority任務亟待注意。至少,這是我記得的! :)