2017-05-24 117 views
0

我寫了一個簡單的工具,它檢查內容的一些xml(解組和內容分析),併爲每個xml寫入一個日誌文件。FixedThreadPool線程數和運行時間

我必須檢查超過幾千個文件,大約2 MB /文件。所以進展需要一些時間。因爲我的文件之間沒有依賴關係,所以我嘗試在不同的線程中完成這項工作(沒有同步的方法)。

不幸的是,我的ExecutorService的東西似乎是錯的。我試圖使用一個fixedthreadpool Executorservice。但是具有1和100線程的運行時間幾乎是一樣的(以及CPU使用率)。只有在每個文件(files.size)使用1個線程的情況下,CPU使用率要高得多(大約90%),運行時間大約是原始運行時間的10%。

我不明白爲什麼1線程的運行時和CPU使用率與100線程相同。

package mycode; 

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class Starter { 

public static void main(String[] args) { 
    File config = new File(args[0]); 
    Starter starter = new Starter(); 
    starter.work(config); 
} 

private void work(File config) 
{ 
    Long start = System.currentTimeMillis(); 
    ConfigReader cr = new ConfigReader(config); 
    cr.init(); 
    FileFinder ff = new FileFinder(); 
    List<File>files = ff.findfiles(cr.getParam("xmlfolder")); 
    List<String>done = new ArrayList<String>(); 


    ExecutorService es = Executors.newFixedThreadPool(Integer.parseInt(cr.getParam("max.threadcount"))); 
    for (File aktuell : files) 
    { 
     es.execute(new Threadstarter(aktuell, cr.getParam("logoutput"), done)); 
    } 



    es.shutdown(); 


    try { 
     es.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES); 

    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    Long end = System.currentTimeMillis(); 
    BufferedWriter logwriter; 
    try { 
     logwriter = new BufferedWriter(new FileWriter(new File(cr.getParam("logoutput")).getAbsolutePath()+"/log.log")); 
     for (String temp : done) 
     { 
      logwriter.write(temp); 
      logwriter.newLine(); 
     } 
     logwriter.write("Die Verarbeitung dauerte "+(end-start)/1000 +" Sekunden"); 
     logwriter.newLine(); 
     logwriter.write("Es wurden "+files.size()+" Dienststellen verarbeitet"); 
     logwriter.flush(); 
     logwriter.close(); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 


} 

} 
+0

當您將'max.threadcount'指定爲1並且將其指定爲100時,您無法找到區別嗎?你可以提供一個最小可重複的代碼,因爲看這段代碼我認爲你應該得到X個並行處理線程,其中X ='max.threadcount'。 – hagrawal

+1

當您僅使用一個線程運行時,該進程花費了多少時間進行計算以及花費了多少時間來執行I/O?您的計算機可能具有多個CPU,因此添加更多的線程可以使其計算速度更快(達到您擁有的CPU數量),但是如果所有這些文件都在同一個磁盤上......只有一個端口用於與磁盤交談。添加更多的線程根本不會改善I/O時間。 –

回答

0

我覺得沒有關係或不容易。這取決於線程正在做的工作。具有一個線程的程序可以佔用100%的CPU,而具有大量線程的程序可以消耗更少的CPU。

如果您正在尋找線程與完成工作之間的優化關係,則必須研究您的情況,並可能找到經驗豐富的解決方案。

0

感謝您的回覆。

正如@hagrawal寫道,使用1,10或100個線程沒有區別。就像我使用盡可能多的線程,因爲我的列表上有文件,我的CPU使用率就會更高(直到CPU成爲瓶頸),整個過程需要大約10%的時間。不幸的是,這需要大量的內存,我擔心,它將在未來導致更多文件的軟件崩潰。

我無法想象,它可能是一個I/O問題。我的機器的raid 0系統應該可以毫不費力地做到這一點。如果我對這個問題的理解是正確的,那麼它就不是I/O問題。因爲如果I/O是瓶頸,如果線程數等於文件數(在我的情況下大約爲1000),性能不應該增加。或者我的薄荷有什麼不對?

不幸的是,CPU使用率與1,10和100線程幾乎完全相同。所以我的印象是,進程從固定數量的線程開始(如配置)並且執行程序服務等待它們全部終止,然後再啓動一個新線程。但我的理解是,只要第一個終止並釋放,它就開始一個新線程?