2016-09-22 5 views
4

私たちが知っているように、ThreadPoolExecutorはいくつかのBlockingQueueを着信タスクのキューとして使用します。私が望むのは、準備が整っているタスク結果のために秒のキューを持つThreadPoolExecutorを持つことです。これらの結果を送信または格納する入出力サービスのソースとしてこのキューを使用したいと思います。同時実行性:受信キューと送信キューの両方でエグゼキュータを実装する方法は?

なぜ別のキューを作成したいのですか?私は結果を得るための行動から結果を送るという行動を切り離したいからです。また、入出力演算に伴う例外や遅延が、結果を計算しているThreadPoolExecutorに影響を与えてはならないと思います。

私はこれのいくつかの素朴な実装を作成しました。私はこれについていくつかの批評をしたいと思います。おそらく、すぐに使えるJavaクラスを使って実装できますか?私はあなたがインターセプトするメソッドの数を持っているスレッドプールエグゼキュータを拡張することができ

... makinfライブラリコンポーネントのためにJavaの7

public class ThreadPoolWithResultQueue { 
    interface Callback<T> { 
     void complete(T t); 
    } 
    public abstract static class CallbackTask<T> implements Runnable { 
     private final Callback callback; 
     CallbackTask(Callback callback) { 
      this.callback = callback; 
     }  
     public abstract T execute(); 
     final public void run() { 
      T t = execute(); 
      callback.complete(t); 
     } 
    } 
    public static class CallBackTaskString extends CallbackTask<String> { 
     public CallBackTaskString(Callback callback) { 
      super(callback); 
     } 
     @Override 
     public String execute() { 
      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
      } 
      return hashCode() + "-" + System.currentTimeMillis(); 
     } 
    }  
    public static void main(String[] args) throws InterruptedException { 
     BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(); 
     final BlockingQueue<String> resultQueue = new LinkedBlockingQueue<String>(); 
     Callback<String> addToQueueCallback = new Callback<String>() { 
      @Override 
      public void complete(String s) { 
       System.out.println("Adding Result To Queue " + s); 
       resultQueue.add(s); //adding to outgoing queue. some other executor (or same one?) will process it 
      } 
     }; 
     ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 1000l, TimeUnit.DAYS, workQueue); 
     for (int i = 0; i <= 5; i++) { 
      executor.submit(new CallBackTaskString(addToQueueCallback)); 
     }; 
     System.out.println("All submitted."); 
     executor.shutdown(); 
     executor.awaitTermination(10l, TimeUnit.SECONDS); 
     System.out.println("Result queue size " + resultQueue.size()); 
    } 
} 
+0

余分な 'Callback'をそこに置いて、コードがより巧妙に見えるようにしましたか、それともそうする必要がありますか?単純な実装ではもう1つのキューが必要です。キューに物を入れる方法が分かっている場合は、明らかにする必要があります。 – Kayaman

+4

一つの単語: 'ExecutorCompletionService'。 –

+0

Kayaman、はい実行するRunnableの出力キューに結果を追加する方が簡単です。しかし、私は可能な限りデカップリングを試みます。とにかく、Markoは素晴らしいことを提案しました。 – MiamiBeach

答えて

0

を使用し、あなたは物事をラップする必要があります送信されたタスクは、コンストラクタで渡されたキューに物をキューイングします。

これは基本的にはExecutorCompletionServiceですが、ユーザーはキューにプラグインするのではなく、キューに入れることができます。

それ以外の場合は、これは一般的なタスクのプロキシです。公正な仕事。

関連する問題