2014-09-27 108 views
3

我想了解使用線程池的優勢,我寫了這段代碼來查看固定線程池的時間改進。線程池性能

首先,我將池中的線程數設置爲1,大約需要920 ms,然後我將池中的線程數更改爲2(以及3,4,5,6,7 ... ),花費了1200毫秒,線程同時運行時不應該更快嗎?

當我把它改成緩存的線程池也花了1200毫秒

package threadpool; 

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Example3 { 

public static void main(String[] args) { 

    new Example3(); 

} 

public Example3() { 

    try { 
     testFixedPool(1); 
     //testFixedPool(2); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

} 

public void testFixedPool(int numberOfThreads) throws InterruptedException { 

    ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); 

    long start = System.currentTimeMillis(); 

    executor.execute(new TaskPrintInteger(0, 10000)); 
    executor.execute(new TaskPrintInteger(1, 10000)); 
    executor.execute(new TaskPrintInteger(2, 10000)); 
    executor.execute(new TaskPrintInteger(3, 10000)); 
    executor.execute(new TaskPrintInteger(4, 10000)); 
    executor.execute(new TaskPrintInteger(5, 10000)); 
    executor.execute(new TaskPrintInteger(6, 10000)); 
    executor.execute(new TaskPrintInteger(7, 10000)); 
    executor.execute(new TaskPrintInteger(8, 10000)); 
    executor.execute(new TaskPrintInteger(9, 10000)); 
    executor.shutdown(); 

    while(!executor.isTerminated()){ 
    } 

    System.out.println(); 
    System.out.println((System.currentTimeMillis()) - start); 
} 

private class TaskPrintInteger implements Runnable { 

    private int number, times; 

    public TaskPrintInteger(int number, int times) { 

     this.number = number; 
     this.times = times; 
    } 

    @Override 
    public void run() { 

     for (int i = 0; i < times; i++) { 
      System.out.println(number); 
     } 

    } 

} 

} 
+5

而不是10個任務,嘗試提交100000個任務。並且不要讓它們打印到'System.out'中,因爲它會同步(所以一次只能打印一個線程,否定線程的任何優點)。 – immibis 2014-09-27 11:55:51

+2

@immibis這裏的關鍵確實是'System.out.println()'調用的同步。這一點以及並行處理不會提升任何I/O綁定進程的事實。 – biziclop 2014-09-27 12:06:08

回答

5

你問很多線程都開展一個活動,這是最有可能(但不一定是)​​:

System.out.println(number); 

讓我們假設你有一個person,你問她在一張紙上寫「10」,每行一個字。

現在,你需要在一張紙上寫上「one」和「two」,每行10次,每行一個字;哪個會更快?

  1. 使用您在上面
  2. 使用相同的一個人問的人帶來一個朋友寫的「兩化」秒。除了規則是他們從大廳的一端開始,並且都跑到紙上。首先到達那裏的人寫下他們的話。現在他們跑回到大廳的另一端,重複這個過程,直到寫完所有單詞。

我會冒險猜測第一個選擇會更快。

想象一下,5人都試圖寫下他們的單詞10,000次的情況是一樣的嗎?混沌?是!

如果您希望從線程中看到真正的改進,那麼任務應完全隔離而不會同步。尤其是沒有IO!

1

當你有一個滿足的資源時,線程的最佳數量可以是1.寫入控制檯是昂貴且單線程的,所以當你使用多線程時,你會增加開銷,而不是讓你的程序更快。線程獨立運行時效果最好。