[英]Reading multiple files in multithreaded mode
我有ArrayList
。 它包含大約20,000個文件路徑元素。
private List<Path> listOfPaths = new ArrayList<>();
我想以多線程模式讀取這些路徑上文件的內容。 問題在於此代碼運行非常緩慢。 如何選擇幾個線程,以便每個線程讀取文件並將其寫入dto
? 如何解決一個線程開始處理文件的問題,以便另一個線程對同一文件不做同樣的事情?
我創建ioPool的目的是為了不阻止io操作使用common-pool(默認用於並行流操作)。 通常建議您在執行io操作時,可以創建core-count* 2
線程,但實際上它在io方面受到限制,就像其他人提到的那樣。
您可以按照以下步驟進行操作。 這不會按順序處理您的文件列表。
ForkJoinPool ioPool = new ForkJoinPool(8);
ForkJoinTask<?> tasks = ioPool.submit(
() -> pathList.parallelStream().forEach(//your code here);
tasks.get(); // this blocks until all threads finishes in the pool
您可以將工作分成較小的塊,每個線程處理所有文件的一部分。 每個線程都有自己要處理的數據的子列表和已處理的數據的列表,以避免嘗試同時讀取/寫入相同數據的任何風險。 當所有線程都完成后,您將確定結果。
實際上,您可以讓Java 8並行流為您完成拆分/合並等艱巨的工作。
使用標准流而不使用多個線程:
List<ParamsDTO> paramsList = listOfPaths.stream().map(p -> readFile(p)).collect(Collectors.toList());
使用並行流提高性能:
List<ParamsDTO> paramsList = listOfPaths.parallelStream().map(p -> readFile(p)).collect(Collectors.toList());
您將函數readFile定義為類似以下內容的位置:
public ParamDTO readFile(Path p) {
ParamsDTO params = new ParamsDTO();
params.setParams(Files.readAllBytes(path));
return params;
}
從長遠來看,您可能希望超越此限制,根據磁盤類型控制並行度,並獲得更多控制權,請使用Java 5執行程序來管理線程池特征以及任務的普通可運行或將來執行。跑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.