2017-05-08 242 views
0

我應該在每個方法調用中創建新的ExecutorService還是每個類使用一個?在性能方面哪個是首選?ExecutorService - 在方法中創建新實例vs每個類創建一個實例

public class NotificationService { 

    public void sendNotification(User recipient) { 

     ExecutorService notificationsPool = Executors.newFixedThreadPool(10); 

     // code 

     notificationsPool.shutdown(); 
    } 
} 

或者

public class NotificationService { 

    ExecutorService notificationsPool = Executors.newFixedThreadPool(10); 

    public void sendNotification(User recipient) { 

     // code 
    } 
} 
+2

您不會根據性能選擇此選項。你根據需要選擇它。你是否需要10個新線程向用戶發送通知?如果只使用其中一個線程,那麼擁有10個可重用線程池有什麼意義?(假設這就是向用戶發送通知的方法)? –

+0

用戶可能與1個以上的密鑰相關。但是,這不是在發佈之前修改的好代碼示例。 – Justas

回答

1

在您的第一個代碼段的ExecutorService是本地的,即,一個新的ExecutorService在每個方法調用創建和ExecutorService在方法結束時被終止。因此,下次運行該方法時線程不會重用。在第二個片段中,只要NotificationService實例處於活動狀態,ExecutorService及其線程就會保留。正如你所看到的,不僅有更少的ExecutorService實例需要GC'd,而且還有更少的線程可以創建,並且可以重複使用。作爲額外的獎勵,第二種方法在創建ExecutorService之後不會產生線程創建的任何預熱時間。

如果您有多個NotificationService實例,則應聲明notificationsPoolstatic,以便在所有實例之間共享池及其線程。

如果所需的線程數量取決於必須發送的通知的數量,請使用緩存的線程池(ExecutorService#newCachedThreadPool()),可能有一個上限。

1

這取決於兩個問題:

  • 你需要什麼級別的並行化?
  • 你可以接受多少開銷?

你真的需要10個線程來解決函數中的問題嗎?你需要能夠,兩次處理該函數(從而給它20個線程)?你是否有資源,這樣做?

或者如果將一個threadPool分配給該類會發生什麼?您是否可能遇到問題(由於線程池被用盡而阻塞)?

如果給定足夠的資源,如果要解決的任務足夠大,以證明每次調用該函數時創建該執行程序的開銷,則選項1可能會更快。雖然老實說,我幾乎無法想象這個激烈的通知。

因此,沒有更多的信息,我會指向選項2(假設它當然是靜態的)。你也可以看看新的WorkStealingPool,它可以幫助你使用精確的並行度。