2013-10-04 62 views
2

我正在使用ThreadPoolexecutor通過用傳統線程替換它。線程池執行程序的優化-java

我已經創建執行如下:

pool = new ThreadPoolExecutor(coreSize, size, 0L, TimeUnit.MILLISECONDS, 
     new LinkedBlockingQueue<Runnable>(coreSize), 
     new CustomThreadFactory(name), 
     new CustomRejectionExecutionHandler()); 
pool.prestartAllCoreThreads(); 

這裏磁芯尺寸是maxpoolsize/5。我已經預先啓動了大約160個線程啓動應用程序的所有核心線程。

在傳統設計中,我們創建並開始圍繞670個線程。

但問題是,即使在使用Executor並創建和替換舊版設計之後,我們並沒有得到更好的結果。

對於結果內存管理,我們使用top命令來查看內存使用情況。 我們已經在millis中放置了System.currentTime的記錄器來檢查使用情況。

請告訴如何優化此設計。謝謝。

+1

你並沒有給我們太多的工作在這裏。我會說你錯過了一個助焊劑電容器。 –

回答

3

但問題是,即使使用Executor並創建並替換舊版設計,我們也沒有得到更好的結果。

我假設你正在看你的應用程序的整體吞吐量,你是不是看到了更好的性能,而不是在自己的線程運行的每個任務 - 即不與池?

這聽起來像你沒有因上下文切換而被阻止。也許你的應用程序是IO綁定的或以其他方式等待其他系統資源。 670個線程聽起來很多,你會使用大量的線程堆棧內存,否則它可能不會阻止你的應用程序的性能。

通常我們使用ExecutorService類不一定是因爲它們比原始線程更快但是因爲代碼更容易管理。併發類會從您的手中處理大量的鎖定,排隊等。

夫婦代碼註釋:

  • 我不知道你想要的LinkedBlockingQueue由核心大小的限制。這是兩個不同的數字。 core-size是池中的最小線程數。 BlockingQueue的大小是多少個作業可以排隊等待一個空閒線程。

  • 順便說一句,在ThreadPoolExecutor絕不會分配一個線程過去核心線程數,除非BlockingQueue滿。在你的情況下,如果所有的核心線程都很忙,並且隊列已滿,並且排隊的任務的核心數量是下一個線程分叉的時候。我不需要使用pool.prestartAllCoreThreads();。一旦任務被提交到池中,核心線程就會啓動,所以我認爲它不會給你帶來太多的收入 - 至少不會有長時間運行的應用程序。

對於時間,我們已經把系統的記錄器。以毫秒爲單位的當前時間來檢查使用情況。

請注意這一點。過多的記錄器可能會影響應用程序的性能,而不是重新構建它。但我假設你在之後添加了記錄器,但你沒有看到性能改進。

0

執行程序僅包含線程的創建/使用,所以它沒有做任何神奇的事情。

這聽起來像你在其他地方有一個瓶頸。你是否鎖定一個對象?你有一個單線程資源,每個線程命中?在這種情況下,你不會看到任何行爲改變。

您的進程是否受CPU限制?如果是這樣,你的線程應該(非常粗略地說)匹配可用處理內核的數量。請注意,您創建的每個線程都會爲其堆棧消耗內存,並且如果您要綁定內存,那麼創建多個線程對此無濟於事。