2011-08-12 7 views
1

を処理スレッドは、スレッドがいくつかの識別方式に基づいて与えられたタスクを処理するかを決定する実行ポリシーを実装するための良い方法はありますか?それとも良いアプローチですか?ThreadPoolExecutor - 指定与えられたタスク

私は、インターリーブチャンクで送信されます1 - 多くのファイルを処理する必要があります。チャンクが到着すると、そのチャンクを処理しないようにしたいと思っています。キャッチすることは、私は処理コードをスレッドセーフにするという贅沢を持たないということです。プール内のスレッドがファイルからチャンクを処理すると、そのファイルの残りの部分を処理するために同じスレッドが必要になります。スレッドが複数のファイルを一度に処理しているかどうかは気にしませんが、同じファイルを同時に処理するプールから複数のスレッドを持つことはできません。

かを判断するために実行ポリシーを使用することができ書籍「実践でのJava並行処理」状態「何のスレッドでは、タスクが実行されるのですか?」が、私はどのように把握していません。

おかげで

答えて

3

さて、あなたはあなた自身のThreadPoolExecutorを書くことができます - しかし、一般的にこれを行う方法はありません。スレッドプールの全体的なポイントは、どのスレッドがどのタスクを取得するか心配することなく、ただちに作業を行うことです。この場合はスレッドを自分で管理し、どのスレッドがどのファイルを扱っているかのマップを保持する必要があるようです。ファイルが終了したとき

あなたは知っていますか?そうでない場合、あなたは...潜在的に増え続けるマップに問題があるために

+0

ThreadPoolExecutorコードの大部分を再利用し、execute()の前にフィルタを追加するだけで済みますが、あなたのパターンはThreadPoolExecutorが意図するものと実際には一致しないことに同意します。 – ptyx

+1

Jonのソリューションは実装が非常に簡単です。スレッドプールを使用する必要がありますが、単一のスレッド(Executors.newSingleThreadExecutor())を持つ各プールは1つのファイルに関連付けられています。チャンクが到着したら、map.get(fileName(chunk))。execute(new TaskChunk(chunk))を呼び出します。スレッド数を制限したい場合は、各スレッドに多くのファイル名を関連付けることもできます。 – toto2

+0

私はファイルの最後のバイトセットを受け取ったときを知っています...私の印象は、実行からタスクのサブミッションを分離することが理想的であり、私が引用した本のステートメントは、ThreadPoolExecutorが私はちょうど政策部分を実装する必要があります。処理コードをスレッドセーフにすることができれば、これにより柔軟性が増します。私はもともと説明された方法を考え、そのアプローチをとるかもしれません。 – sethro

0

をつもりは良いアイデアは、ファイルごとのスレッドのようになります。

HashMap<String, MyThreadImplementer> fileToThreadMap... 

class MyThreadImplementer implements Runnable { 
    int maxNumParts; 
    private List<FileChunk> chunkList... 
    private List<FileChunk> doneChunks... 

    public MyThreadImplementer(int maxNumberOfParts) { 
     maxNumParts=maxNumberOfParts; 
    } 

    public void run() { 
     while(doneChunks.size() < maxNumParts) { 
      Thread.sleep(...) 
      if (!chunkList.isEmpty()) { 
       process each chunk in list and mvoe to done chunks 
      } 
     } 
    } 
} 

しかし、あなたは、あなたに注意する必要があるだろう1000個のファイルを処理しないで、1000個のスレッドを作成します。

0

は、あなたが「処理コードスレッドセーフを作る余裕が全くない」と言うことありませんが、これは、特定のスレッドにファイルをマップする必要があることを意味するものではありません。それは、そのファイルからの最後のチャンクが処理を終えるまで、ファイルから次のチャンクの処理を開始できないことを意味します。

java.util.concurrentを利用すると、メインスレッドでMap<String, LinkedBlockingQueue<FileChunk>>(ファイル名をキーとする)を維持し、チャンクが入ってくるごとにそれぞれのチャンクをそれぞれのファイルのキューに割り当てることができます。Runnableをブロックします各キュー。

その方法は、一度に1つだけのスレッドが任意のファイルを処理することになります。また、スレッドを直接混乱させたり、複数のスレッドプールを維持する必要はありません。

関連する問題