2009-09-18 28 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

相关问题