2017-05-10 132 views
1

根據我的理解,越來越多的threads或進入並行會減少時間,但在這裏,我看到一個緩慢的Object.hashCode,它佔用了兩倍的時間來計算默認的哈希碼對同一數量的對象運行4個線程vs 1個線程。多線程減慢程序的速度

我認爲這需要花費相當的時間或更少的時間來並行執行此操作。

但是當我們運行下面的代碼。我們可以看到,每個線程都有相同的工作量,因此您希望運行4個線程可能需要大約與運行單個線程相同的時間。

我看到~4秒爲2.3秒,而1秒爲0.9秒。

public class Test { 

    private static final int THREAD_COUNT = 1; 
    private static final int ITERATIONS = 20000000; 

    public static void main(final String[] args) throws Exception { 
     long start = System.currentTimeMillis(); 
     new Test().run(); 
     System.err.println(System.currentTimeMillis() - start); 
    } 

    private final ExecutorService service = Executors.newFixedThreadPool(THREAD_COUNT, new ThreadFactory() { 
     private final ThreadFactory factory = Executors.defaultThreadFactory(); 

     @Override 
     public Thread newThread(final Runnable r) { 
      Thread thread = factory.newThread(r); 
      thread.setDaemon(true); 
      return thread; 
     } 
    }); 

    private void run() throws Exception { 
     Callable<Void> work = new java.util.concurrent.Callable<Void>() { 
      @Override 
      public Void call() throws Exception { 
       for (int i = 0; i < ITERATIONS; i++) { 
        Object object = new Object(); 
        object.hashCode(); 
       } 
       return null; 
      } 
     }; 
     @SuppressWarnings("unchecked") 
     Callable<Void>[] allWork = new Callable[THREAD_COUNT]; 
     Arrays.fill(allWork, work); 
     List<Future<Void>> futures = service.invokeAll(Arrays.asList(allWork)); 
     for (Future<Void> future : futures) { 
      future.get(); 
     } 
    } 

} 

注:我看到這篇文章C# Multithreading但因爲它是C#所以我能夠掌握它,有人能幫助我理解從JVM的角度

+0

線程並沒有真正做任何工作,因爲它只是放棄了'hashCode()'的結果。所以JIT編譯器可能會跳過'call()'內的整個循環,除非我錯了。 'call()'方法目前看起來很沒用,因爲它總是返回'null'。 –

+0

爲了記錄:您已閱讀此:http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – GhostCat

+0

在查看代碼後,它應該要注意的是,如果1個線程執行W個工作量(操作),則N個線程執行N * W個操作。因此,並行減少執行時間並非如此。這個代碼根本不需要多線程。 – Eugene

回答

1

相同的,如果我走"new Object()"在循環之外,我看到相對多線程性能的顯着提高。

似乎"new Object()"將消除GC干擾。

在這種情況下,默認的hashCode涉及:

  1. 計算一個hashcode
  2. 經由原子compare-and-swap操作

在緊張的使用原子CAS的安裝此進object頭循環有效地串行化功能代碼的核心部分,導致連續執行相當大比例的"work loop"

+0

感謝剛剛在谷歌上搜索答案時發現... :) –

+0

@ GhostCat-不,我現在得到了我的答案,明白每一件事情 –

相關問題