2

我試圖提高索引我的lucene文件的性能。爲此,我創建了一名工作人員「LuceneWorker」來完成這項工作。設計問題:這隻適用於生產者/消費者嗎?

鑑於下面的代碼,'併發'執行變得非常慢。我想我知道爲什麼 - 這是因爲期貨增長到極限,幾乎沒有內存可以執行LuceneWorker的另一項任務。

問:有沒有辦法限制進入執行者的「工人」數量?換句話說,如果有'n'期貨 - 不要繼續並且允許文件首先被索引?

我的直觀方法是我應該用ArrayBlockingQueue構建一個消費者/生產者。但是,在我重新設計它之前,我想知道我是否合適。

 ExecutorService executor = Executors.newFixedThreadPool(cores); 
     List<Future<List<Document>>> futures = new ArrayList<Future<List<Document>>>(3); 
     for (File file : files) 
     { 
      if (isFileIndexingOK(file)) 
      { 
       System.out.println(file.getName()); 
       Future<List<Document>> future = executor.submit(new LuceneWorker(file, indexSearcher)); 
       futures.add(future); 
      } 
      else 
      { 
       System.out.println("NOT A VALID FILE FOR INDEXING: "+file.getName()); 
       continue; 
      } 
     } 

     int index=0; 
     for (Future<List<Document>> future : futures) 
     { 
      try{ 

       List<Document> docs = future.get(); 

       for(Document doc : docs) 
        writer.addDocument(doc);  


      }catch(Exception exp) 
      { 
       //exp code comes here. 
      } 
     } 

回答

1

如果你想限制等待作業的數量,使用ThreadPoolExecutor與像ArrayBlockingQueue有界隊列。同時滾動您自己的RejectedExecutionHandler,以便提交線程等待隊列中的容量。您無法使用Executors中的便利方法,因爲newFixedThreadPool使用無限制的LinkedBlockingQueue

1

根據標準輸入大小和LuceneWorker類的複雜性,我可以想象至少部分地使用Fork/Join框架來解決這個問題。當使用JDK 8的CountedCompleter實現(包含在jsr166y中)時,I/O操作不會產生任何問題。