2013-05-16 28 views
4

爲了更好地理解線程在Java中,我寫了下面的代碼爲什麼線程工作在單核CPU上?

public class SimpleRunnableTest { 
    public static void main(String[] args) throws InterruptedException { 
     long start = System.currentTimeMillis(); 

     Thread t1 = new Thread(new TT1()); 
     t1.start(); 
     Thread t2 = new Thread(new TT2()); 
     t2.start(); 

     t2.join(); 
     t1.join(); 

     long end = System.currentTimeMillis(); 
     System.out.println("end-start="+(end-start)); 
     } 
} 
class TT1 implements Runnable { 
    public void run(){ 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class TT2 implements Runnable { 
    public void run() { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}  

的想法是,如果我跑Thread.sleep(5000)Thread.sleep(1000)依次main線程,所消耗的時間會6 sec,但因爲我使用的線程,它在多核CPU機器上僅花費5 sec,並且它確實。但我的問題是:

爲什麼在單核CPU機器上仍然是5 sec?當然使用了Threading,但是不是隻是模擬線程時分複用

我對時分複用的理解是:假設Thread.sleep(5000)是任務A,Thread.sleep(1000)是任務B,我們可以將它拆分爲:A1,A2,A3; B1,B2

順序就是:A1,A2,A3,B1,B2

時分複用線程只是:A1,B1,A2,B2,A3

如果是,怎麼來的第一個花費6秒,第二個花費5秒?

我在這裏的基地嗎?

+6

一旦進入休眠狀態,就會發生線程上下文切換,然後另一個執行(也將進入休眠狀態)。 –

+0

線程的實現取決於系統構建器,一個系統是綠色的,另一個是紫色的。你更喜歡哪個? –

回答

11

結果是5,而不是6,因爲兩個線程可以同時睡眠。通過調用Thread.sleep()進入睡眠模式可讓其他線程運行,但剩餘的睡眠間隔計時器繼續爲兩個線程打勾。

請注意,這僅適用於睡眠(使用幾乎爲零的CPU),但不適用於做有用的工作:在這種情況下,單核非超線程CPU上的計時實際上是累加的。例如,如果一個線程需要進行5秒鐘的數字運算,而另一個線程需要進行第二輪數字運算,那麼這兩個線程的總時間爲6秒。

+0

哦,這是一個好點,我會去測試它 – Will

+1

剛剛測試過,你是對的。如果任務是實際任務而不是睡眠,線程不會影響「單核非超線程CPU」消耗的總時間,感謝幫助:) – Will

1

通過調用Thread.sleep(sleeptime),Thread告訴它至少'sleeptime'millis不需要CPU。

與此同時另一個線程可以執行。

+0

但是它們不能同時睡眠',對嗎?在CPU級別上,「同一時間」是通過「時分多路複用」實現的,這意味着真正發生的是A睡眠一段時間,然後是B,然後是A,然後是B ...,因爲時間間隔是對於每個線程來說都很小,這就造成了「同時睡眠」的錯覺,這不是多線程技術如何在單核CPU上首先實現的嗎?因爲無論如何,一個CPU不能一次執行多個命令,對吧? – Will

+0

「睡眠」在這裏是「無所事事」的同義詞 - 兩條線程應該避免什麼都不能並行?此外,即使在單個核心上,當前使用流水線和預測的CPU設計也可以並行執行很多操作 – mschenk74

相關問題