2015-12-16 38 views
1

我已經創建了一個類來計算同一目錄中給定文件中的單詞。鑑於文件非常大,我決定使用多線程實現多個文件的計數。LinkedBlockingQueue只返回多個線程之一

當按照以下指定的方式運行DriverClass時,它會卡在第一個線程中。 我在做什麼錯?在我遍歷queue.take()時,人們會期望解析器等待某些東西來檢索並繼續前進。在線程1中卡住會讓我懷疑將()放入隊列時出錯。

謝謝,提前!

DriverClass:

public class WordCountTest { 
    public static void main(String[] args){ 
     if (args.length<1){ 
      System.out.println("Please specify, atleast, one file"); 
     } 
     BlockingQueue<Integer> threadQueue = new LinkedBlockingQueue<>(); 
     Runnable r; 
     Thread t; 

     for (int i = 0; i<args.length; i++){ 
      r = new WordCount(args[i], threadQueue); 
      t = new Thread(r); 
      t.start(); 

      int total = 0; 
      for (int k = 0; k<args.length; k++){ 
       try { 
        total += threadQueue.take(); 
       } catch (InterruptedException e){ 
       } 
      } 
      System.out.println("Total wordcount: " + total); 
     } 
    } 
} 

WordCountClass:

public class WordCount implements Runnable { 
    private int myId = 0; 
    private String _file; 
    private BlockingQueue<Integer> _queue; 
    private static int id = 0; 

    public WordCount(String file, BlockingQueue<Integer> queue){ 
     _queue = queue; 
     _file = file; 
     myId = ++id; 
    } 

    @Override 
    public void run() { 
     System.out.println("Thread " + myId + " running"); 
     try { 
      _queue.put(countWord(_file)); 
     } catch (InterruptedException e){ 

     } 
    } 

    public int countWord(String file){ 
     int count = 0; 
     try { 
      Scanner in = new Scanner(new FileReader(file)); 
      while (in.hasNext()){ 
       count++; 
       in.next(); 
      } 
     } catch (IOException e){ 
      System.out.println("File," + file + ",not found"); 
     } 
     return count; 
    } 
} 

回答

1

的問題是,您使用的是嵌套循環,當你要使用兩個單獨的循環:一個啓動WordCounts,另一個收集的結果,像

public class WordCountTest { 
    public static void main(String[] args){ 
     Queue<Integer> threadQueue = new ConcurrentLinkedQueue<>(); 
     ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 

     CountDownLatch latch = new CountDownLatch(args.length); 

     for (int i = 0; i<args.length; i++){ 
      CompletableFuture.runAsync(new WordCount(args[i], threadQueue), executor) 
       .thenRunAsync(latch.countDown(), executor); 
     } 

     latch.await(); 

     int sum = 0; 
     for(Integer i : threadQueue) { 
      sum += i; 
     } 
    } 
} 

或者不過你想要的要實現它,重點是你不應該開始收集結果,直到所有的WordCounts已經開始。

+0

是的,我來到相同的解決方案,並已實施它,在這個答案之前。無論如何謝謝你! - 我已將您的答案標記爲最終答案。感謝您的時間! –

1

第一線程啓動後,您正在等待所有的結果。也許你打算等待所有線程開始後的結果。

注意:如果創建的線程多於擁有CPU的線程,則可能會變慢。我建議使用固定的線程池。

+1

通過CPU的線程數已被另外實現。正如我剛剛提到的上面的答案,正如我正在寫這篇文章,我已經找到了嵌套循環的錯誤,並通過使用兩個獨立的循環來修復它 - 一個用於啓動線程,一個用於提取結果。儘管謝謝你的激情! –