2012-11-06 19 views

回答

6

最好的辦法是利用執行人服務API來管理一個線程池,而不是開始對自己的一個開放式的線程數的。

ExecutorService pool = Executors.newCachedThreadPool(); 
for (Runnable r : new Runnable[] { 
    new R() { void r() { myMethod1(); }}, 
    new R() { void r() { myMethod2(); }}, 
}) 
    pool.execute(r); 
pool.shutdown(); 
pool.awaitTermination(60, TimeUnit.SECONDS); 

abstract class R implements Runnable 
    public final void run() { r(); } 
    abstract void r(); 
} 

請注意,這是不可取的堅持在其自己的,獨立的線程運行的每一個方法。線程相當重量級(每個線程分配一個完整的調用棧),並且性能實際上隨線程數量增加遠遠超出可用處理器內核的數量而降低。

+0

使用執行程序有什麼好處? – damienix

+0

@damienix它們結合了一個隊列和一個線程池,允許您重新使用線程,爲單個任務收集結果/異常,取消任務以及關閉線程池作爲一個整體。 –

+0

添加到彼得的觀點,線程池是靈活和可配置的方式來啓動和停止線程。從Java 5開始,'Thread'僅被視爲低級類。 –

2

我的解決辦法是

功能:

public void runParallel(Runnable... runnables) throws InterruptedException { 

List<Thread> threads = new ArrayList<Thread>(runnables.length); 

for (Runnable runnable :runnables) { 
    Thread th = new Thread(runnable); 
    threads.add(th); 
    th.start(); 
} 

for (Thread th : threads) { 
    th.join(); 
} 

用途:

runParallel(new Runnable() { 
       @Override 
       public void run() { 
        method1() 
       } 
      }, new Runnable() { 
       @Override 
       public void run() { 
        method2() 
       } 
      } 
); 

更好的想法?也許有是我不知道的一個較短的方式;)

+0

以供將來參考,它是有道理的編輯答案只有糾正和改進已經提出的觀點;用你自己的代碼完全替代原來的代碼只是意味着你通過別人的口說話,upvotes和downvotes去原來的回答者。順便說一句,謝謝你指出我的R類錯誤;糾正。 –

+0

我真的不知道我應該在哪裏放置代碼的建議給你,評論這是一個好地方。我可能已經改變了太多,正如你注意到的。無論如何,謝謝你的答案。 – damienix

+0

的首選(甚至預計)的方法是將你已經到了你的問題的代碼,所以應答者對他們的貢獻清晰的起點。 –

2

我更喜歡這樣的事情:

public static void runParallel(Runnable... runnables) throws InterruptedException { 
    final CountDownLatch done = new CountDownLatch(runnables.length); 
    for (final Runnable r: runnables) { 
     new Thread(new Runnable() { 
      public void run() { 
       try { 
        r.run(); 
       } finally { 
        done.countDown(); 
       } 
      } 
     }).start(); 
    } 
    done.await(); 
} 

這種方法的優點是,它也可以與線程池(即可以取代new Thread(...).start()executor.submit(...))。

此外,它允許您使用基於awaitTermination(),迫使你創建的每個調用新池預先存在的線程池,不同的解決方案。

+0

有一個完整的例子[這裏](http://stackoverflow.com/a/11372932/230513)。 – trashgod

+0

但'executor.submit(runnable).get()'做同樣的事情,沒有在客戶端的部分努力。 –

0

damienix給出的API:

public void runParallel(Runnable... runnables) throws InterruptedException { 
    final ExecutorService pool = Executors.newFixedThreadPool(runnables.length); 
    for (Runnable runnable: runnables) { 
     pool.submit(runnable); 
    } 
    pool.shutdown(); 
    pool.awaitTermination(1, TimeUnit.MINUTES); 
} 
相關問題