2

プログラムの一般的な目的

コマンドラインからbashパターンと指定された場所を読み取り、その場所でそのパターンに一致するすべてのファイルを見つけるには、プログラムをマルチスレッドにする必要があります。

プログラムの一般的な構造

  • 引数を解析して他のクラスを開始するドライバー/メインクラス。
  • 後で処理するために、指定されたルートディレクトリから見つかったすべてのディレクトリアドレスを文字列配列に追加するProcessDirectoriesクラス
  • 上記のクラスで見つかったアドレスを保持するDirectoryDataクラス
  • 見つかった各ディレクトリを調べ、パターンに一致するファイルを文字列配列に追加して後で結果を出力するProcessMatchesクラス
  • メイン/ドライバーがもう一度引き継ぎ、結果を出力します:)

問題

ProcessDirectoriesクラスがまだ機能している間でも、一致を処理する必要があります(効率を上げるために、作業を行う前にリストが入力されるのを不必要に待つ必要はありません)。これを行うには、次のことを試みます。a)DirectoryDataが空の場合はProcessMatchesスレッドをwait()にします。b)新しいエントリが追加された場合はProcessDirectories notifyAll()を作成します。

質問 :)

私が見るすべてのチュートリアルは、プロデューサーとコンシューマーが同じオブジェクト内にあること、または1つのデータ構造のみを扱うことに焦点を当てています。生成と消費に複数のデータ構造と複数のクラスを使用している場合、どうすればこれを行うことができますか?

4

2 に答える 2

1

2つのスレッドが相互に通信するデータに関連付けられた1つのデータ構造があります。これは、「キューからデータを取得し、空の場合は待機します」および「データをキューに入れ、満杯の場合は待機します」機能を持つキューにすることができます。これらの関数は、内部でキュー自体を呼び出しnotifywaitそのキューに同期する必要があります。

于 2012-11-19T14:49:56.530 に答える
1

次のようなものはどうですか?

class Driver(String args)
{
   ProcessDirectories pd = ...
   BlockingQueue<DirectoryData> dirQueue = new LinkedBlockingQueue<DirectoryData>();
   new Thread(new Runnable(){public void run(){pd.addDirs(dirQueue);}}).start();

   ProcessMatches pm = ...
   BlockingQueue<File> fileQueue = new LinkedBlockingQueue<File>();
   new Thread(new Runnable()
     {
       public void run()
       { 
         for (DirectoryData dir = dirQueue.take(); dir != DIR_POISON; dir = dirQueue.take())
         {
           for (File file : dir.getFiles())
           {
             if (pm.matches(data))
               fileQueue.add(file)
           }
         }
         fileQueue.add(FILE_POISON);
       }
     }).start();

   for (File file = fileQueue.take(); file != FILE_POISON; file = fileQueue.take())
   {
     output(file);
   }
}

もちろん、これは大まかなアイデアです。 オブジェクトをキューProcessDirectories.addDirs()に追加するだけです。DirectoryData本番環境では、スレッドに名前を付ける必要があります。おそらく、エグゼキュータを使用して管理スレッドを提供します。おそらく、毒メッセージ以外のメカニズムを使用して、処理の終了を示します。また、キューサイズの制限を減らすこともできます。

于 2012-11-19T15:51:47.973 に答える