2017-06-07 10 views
0

私はBlockingQueueでConsumer-Producerの問題を実装しようとしていました。何らかの目的でこれを行うために、私はファイル検索ツールを書くことにしました。Java。 Consumer - BlockingQueueを持つプロデューサ検索ツール

私は、検索メカニズムが再帰的に動作していると判断し、すべての新しいディレクトリに検索の速度を上げるための新しいスレッドプールが追加される予定です。

私の問題は、最終的にスレッドを検索する(消費者)を停止するメカニズムを実装することができないことです。スレッドを検索するとジョブが完了します。

私はPOISON PILLSのようなアイデアでそれをやろうとしていましたが、うまくいきません(スレッドは結果を印刷する前に停止します)。どのように私はそれを行うことができます任意のアイデア?ここ

いくつかのコードである:

機構を検索:

public class SearchingAlgorithm implements Runnable { 

private final File file; 
private BlockingQueue<File> queue; 
private ExecutorService executor; 

public SearchingAlgorithm(File fileName, BlockingQueue<File> queue) { 
    this.file = fileName; 
    this.queue = queue; 
    this.executor = Executors.newWorkStealingPool(); 
} 

@Override 
public void run() { 
    try { 
     searchDeep(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

private void searchDeep() throws InterruptedException { 
    File[] files = file.listFiles(); 
    if (files != null) { 
     for (File fil : files) { 
      if (fil.isDirectory()) { 
       executor.submit(new SearchingAlgorithm(fil, this.queue)); 
      } else { 
       this.queue.add(fil); 
      } 
     } 
    } 
} 

}

プリンタ:

public class ContainingCheckAlgorithm implements Runnable { 

private BlockingQueue<File> queue; 
// private ExecutorService executor; 
private String keyWord; 

public ContainingCheckAlgorithm(BlockingQueue<File> queue, String keyWord) { 
    this.queue = queue; 
    this.keyWord = keyWord; 
    // executor = Executors.newFixedThreadPool(2); 
} 

@Override 
public void run() { 
    try { 
     printFile(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

} 

private void printFile() throws InterruptedException { 
    while (true) { 
     File takeFile = queue.take(); 
     String fileName = takeFile.getAbsolutePath() 
       .toLowerCase(); 
     boolean isContainingKeyWord = fileName.contains(keyWord.toLowerCase()); 

     if (isContainingKeyWord) { 
      System.out.println(takeFile.getAbsolutePath()); 
     } 
    } 
} 

}

メイン試験クラス:

public class MainClass { 

public static void main(String[] args) throws InterruptedException { 
    ExecutorService executor = Executors.newFixedThreadPool(2); 
    BlockingQueue<File> queue = new LinkedBlockingQueue<>(); 

    File fileName = new File("C:/"); 

    SearchingAlgorithm sa = new SearchingAlgorithm(fileName, queue); 
    executor.submit(sa); 

    ContainingCheckAlgorithm ca = new ContainingCheckAlgorithm(queue, "Slipknot"); 
    executor.submit(ca); 

    executor.shutdown(); 
} 

}

答えて

0

スプリット2つの段階における全作業。最初の段階で、SearchingAlgorithmの作業とContainingCheckAlgorithmは、キューが空の場合に新しいジョブを待機します。第2段階では、すべてのSearchingAlgorithmインスタンスが終了し、ContainingCheckAlgorithmがキューを空にすると終了します。キューが空であるかどうかを調べるために、ContainingCheckAlgorithmはqueue.take()の代わりにqueue.poll(timeout)を使用します。

また、それぞれのSearchingAlgorithmに新しいスレッドプールを作成する必要はありません。

0

uが言ったように、私は、このようにそれを実行しよう:

はsearchingAlgorithmの他のinsatancesとアルゴリズムを共有するスレッドプールを検索します。

は、検索:私はメインクラスでスレッドプールを閉じるために、いくつかのメカニズムを必要とするので

​​

今ContainingCheckAlgorithは、メインクラスとされたCountDownLatchを共有する必要があります。また、それはあなたが言ったようにプール(タイムアウト)を使用し、私のスレッドは最終的に自分の仕事を終了します。

CHECKING

public class ContainingCheckAlgorithm implements Runnable { 

private BlockingQueue<File> queue; 
private String keyWord; 
private CountDownLatch latch; 

public ContainingCheckAlgorithm(BlockingQueue<File> queue, String keyWord, CountDownLatch latch) { 
    this.queue = queue; 
    this.keyWord = keyWord; 
    this.latch = latch; 
} 

@Override 
public void run() { 
    try { 
     printFile(); 
     latch.countDown(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

} 

private void printFile() throws InterruptedException { 
    File takeFile; 
    while ((takeFile = queue.poll(1, TimeUnit.SECONDS)) != null) { 
     String fileName = takeFile.getName() 
       .toLowerCase(); 
     boolean isContainingKeyWord = fileName.contains(keyWord.toLowerCase()); 

     if (isContainingKeyWord) { 
      System.out.println(takeFile.getAbsolutePath()); 
     } 
    } 
} 

MAIN:

public class MainClass { 

public static void main(String[] args) throws InterruptedException { 
    ExecutorService executor = Executors.newCachedThreadPool(); 
    BlockingQueue<File> queue = new LinkedBlockingQueue<>(); 
    CountDownLatch latch = new CountDownLatch(1); 

    File fileName = new File("C:/"); 

    SearchingAlgorithm sa = new SearchingAlgorithm(fileName, queue, executor); 
    executor.submit(sa); 

    ContainingCheckAlgorithm ca = new ContainingCheckAlgorithm(queue, "Slipknot", latch); 
    executor.submit(ca); 

    latch.await(); 
    executor.shutdown(); 
} 

それは奇妙に見えますが、私があれば何だろう:

  • よりスレッド1よりもContainingCheckAlgorithmとして実行します?

  • SearchingAlgorithmは1秒以上のファイルを検索し、ContainingCheckAlgorithmは処理を終了しますか?明らかに、タイムアウトを2秒に変更することができますが、私たちは常にプログラムを最適化しようとします。

関連する問題