2012-06-29 16 views
0

Java併發API爲您提供了ExecutorExecutorService接口來構建並附帶幾個具體實現(ThreadPoolExecutorScheduledThreadPoolExecutor)。Java併發性:如何選擇和配置執行程序

我完全不熟悉Java併發性,並且很難找到幾個非常類似的問題的答案。而不是與所有這些微小的問題,以便塞滿我決定把他們捆綁在一起,因爲可能有一種方法來回答他們一舉(可能是因爲我沒有在這裏看到整個畫面):

  • 是它通常的做法是實施你自己的Executor/ExecutorService?在什麼情況下你會這樣做,而不是使用上面提到的兩個結論?在什麼情況下,這兩個結論比「本土」更適合?
  • 我不明白所有併發集合如何與Executor相關。舉例來說,ThreadPoolExecutor是否使用引擎蓋下的ConcurrentLinkedQueue來排隊提交的任務?或者你(API開發者)是否應該在你的並行化的run()方法中選擇和使用ConcurrentLinkedQueue? Basicaly,是那些在Executor內部使用的併發集合,還是用它們來幫助編寫非阻塞算法?
  • 您可以配置Executor在底層使用哪些併發集合(用於存儲提交的任務),這是否是常用操作?

在此先感謝!

回答

3

實施您自己的Executor/ExecutorService是否常見?

不,我從來沒有這樣做過,我一直在使用併發包。這些類的複雜性和圍繞它們「錯誤」的性能影響意味着你應該在進行這樣的項目之前仔細考慮它。

我覺得需要實現自己的執行器服務的唯一時間是當我想實現「自我運行」執行器服務時。直到一位朋友告訴我,有一個way to do it with a RejectedExecutionHandler

我想調整ThreadPoolExecutor的行爲的唯一原因是讓它啓動所有線程直到最大線程,然後然後將作業粘貼到隊列中。默認情況下,ThreadPoolExecutor啓動min-threads,然後在啓動另一個線程之前填充隊列。不是我期望或想要的。但是,我只是從JDK複製代碼並進行更改 - 而不是從頭開始實施。

我不明白所有的併發集合如何與執行程序相關。例如,ThreadPoolExecutor使用下面的ConcurrentLinkedQueue來排隊提交的任務嗎?

如果您正在使用Executors輔助方法之一,那麼您不必擔心這一點。如果您自己實例化ThreadPoolExecutor,那麼您提供了BlockingQueue以供使用。

public static ExecutorService newFixedThreadPool(int nThreads) { 
    return new ThreadPoolExecutor(nThreads, nThreads, 
      0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); 
} 

對戰:

ExecutorService threadPool = 
    new ThreadPoolExecutor(minThreads, maxThreads, 0L, TimeUnit.MILLISECONDS, 
      new SynchronousQueue<Runnable>()); 

你可以配置哪些併發集合一個Executor引擎蓋下使用(儲存提交的任務),並且這是常見的做法?

查看最後一個答案。

+0

感謝@Gray(+1) - 所以總結一下,我會一直使用'ThreadPoolExecutor'或'ScheduledPoolExecutor'和* only *時間來使用併發集合,當我使用它時創建這兩種類型的新實例?作爲我的非阻塞算法的一部分,沒有理由在我的run()方法中出現'BlockingQueue',是的?只是想確定我完全理解! – IAmYourFaja

+0

是的執行者。我一直使用併發集合來在線程之間進行通信,但您不必擔心與執行程序服務有關的問題。在run()方法中沒有任何理由引用'Runnable'阻塞隊列。 – Gray

+0

看到我的例子在這裏設置拒絕處理程序。這引用隊列,但再次,不在'run()'方法:http://stackoverflow.com/questions/11249342/creating-a-dynamic-growing-shrinking-thread-pool-in-java/11249485#11249485 – Gray