2009-09-18 31 views
2

文件:Example1.java爲什麼兩個Java線程(在某些情況下)比一個快兩倍?

public class Example1 implements Runnable { 

    public void run() { 
     for(int i = 0; i < 100000000; i++) { 
      int x = 5; 
      x = x * 4; 
      x = x % 3; 
      x = x + 9000; 
      x = x * 923; 
     } 
    } 

    public static void task() { 
     for(int i = 0; i < 100000000; i++) { 
      int x = 5; 
      x = x * 4; 
      x = x % 3; 
      x = x + 9000; 
      x = x * 923; 
     } 
     for(int i = 0; i < 100000000; i++) { 
      int x = 9; 
      x = x * 2; 
      x = x % 4; 
      x = x + 3241; 
      x = x * 472; 
     } 
    } 

    public static void main(String[] args) { 

     long startTime = System.currentTimeMillis(); 
      Example1.task(); 
      Example1.task(); 
      Example1.task(); 
      Example1.task(); 
      Example1.task(); 
     long stopTime = System.currentTimeMillis(); 
     long runTime = stopTime - startTime; 
     System.out.println("Run time for one thread: " + runTime); 


     startTime = System.Example1(); 
      (new Thread(new Example1())).start(); 
      (new Thread(new Example2())).start(); 
      (new Thread(new Example1())).start(); 
      (new Thread(new Example2())).start(); 
      (new Thread(new Example1())).start(); 
      (new Thread(new Example2())).start(); 
      (new Thread(new Example1())).start(); 
      (new Thread(new Example2())).start(); 
      (new Thread(new Example1())).start(); 
      (new Thread(new Example2())).start(); 
     stopTime = System.currentTimeMillis(); 
     runTime = stopTime - startTime; 
     System.out.println("Run time for two threads: " + runTime); 


    } 

} 

文件:Example2.java

public class Example2 implements Runnable { 

    public void run() { 
     for(int i = 0; i < 100000000; i++) { 
      int x = 9; 
      x = x * 2; 
      x = x % 4; 
      x = x + 3241; 
      x = x * 472; 
     }   
    } 
} 

當我運行它,它輸出:

運行時間爲一個線程:1219

兩個線程的運行時間:281

或者非常接近的東西。

爲什麼會有這樣的差異?爲什麼將它分成兩個線程比直接運行速度快兩倍以上?

+0

我認爲你應該更明確地使用代碼來獲得你正在做什麼的確切想法。 – yeyeyerman 2009-09-19 00:06:08

+0

您也不夠細心,不能將實時編譯考慮在內。您應該在基準開始之前運行代碼,以便JIT能夠完成其工作。 – starblue 2009-09-19 08:26:38

回答

19

你實際上並沒有等待線程完成。

一旦你開始一個線程,你必須調用.join()來等待它完成。這裏發生的事情是,所有的線程都開始了,只要最後一個線程已經開始,你計算它,然後計算停止時間。這意味着你的線程仍然在後臺運行。

編輯:第一個花了這麼長時間的原因是因爲你正在進行一系列的同步調用,而創建一個線程並啓動它會產生一個異步任務。

編輯2:這是在你的第一次測試會發生什麼餐巾紙序列圖: http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0-RXhhbXBsZTE6IFRhc2sgc3RhcnRlZAphY3RpdmF0ZSAAGAgKACEILS0-TWFpbjogZG9uZQpkZQAYEgABWAABWAABgTFlMQo&s=napkin

這裏是你的第二個測試會發生什麼餐巾紙序列圖: http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0tPkFub255bW91cyBUaHJlYWQ6IFN0YXJ0IEV4YW1wbGUxLnRhc2soKQoACSYyAAEuAAFdAAGBOwCCPjoAgyIGPk1haW46ICJIb3cgbG9uZyBkaWQgdGhhdCB0YWtlPyIKAINmEC0AKwhUYXNrcyBiZWdpbiB0byBmaW5pc2guLi4gKHNvbWUgbWF5IGhhdmUgZW5kZWQgZWFybGllcikK&s=napkin

編輯3:我只是意識到第二個順序圖將所有箭頭指向/ same /線程。實際上,每次調用它們都是不同的線程。

+2

+1:WebSequenceDiagrams.com ==很棒。 – Juliet 2009-09-19 03:46:10

+0

對於網絡序列圖+1 :-) – 2009-09-19 07:55:55

2

線程上的調用start()立即返回,因爲它只是排隊線程。 線程本身將在一段時間後開始在後臺運行。

1

以下是我與你的代碼將加入到該線程:

運行時間爲一個線程:566

運行時間兩個線程:294

所以以前答案是正確的。

編輯:我加入了這種方式。你可以做得更好,但沒關係:

Thread[] t = new Thread[10]; 
    (t[0] = new Thread(new Example1())).start(); 
    (t[1] = new Thread(new Example2())).start(); 
    (t[2] = new Thread(new Example1())).start(); 
    (t[3] = new Thread(new Example2())).start(); 
    (t[4] = new Thread(new Example1())).start(); 
    (t[5] = new Thread(new Example2())).start(); 
    (t[6] = new Thread(new Example1())).start(); 
    (t[7] = new Thread(new Example2())).start(); 
    (t[8] = new Thread(new Example1())).start(); 
    (t[9] = new Thread(new Example2())).start(); 

    for (Thread t1: t) { 
     try { 
      t1.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

你必須加入每個線程。但是,您不會浪費時間在join()中等待,因爲其他線程未被阻止。如果線程在調用加入之前完成了它的執行,您只需繼續下一個線程。

另外,您最近的評論是什麼意思?

+0

你在哪裏添加連接?在(new Thread(new Example2()))。start(); ? – 827 2009-09-19 18:22:37

+0

另外,這些更多是我期待的速度差異。 – 827 2009-09-19 18:23:12

+0

是的,您必須在開始列表的最後添加連接(如本例)。如果在兩者之間添加它,則需要等待該線程完成才能開始下一個線程(避免任何形式的並行)。 – Malaxeur 2009-09-19 22:21:22

相關問題