5

シングルスレッドプールのExecutorServiceオブジェクトがあります。将来のある時点で、submit()メソッドを使用して実行するタスクが追加されます。私の理解では、submitは、実行するタスクのリストの最後に、送信されたRunnableを追加して送信します。ただし、ブール値に基づいて、実行するタスクの前にランナブルを送信したい場合があります。これが現在のタスクに影響を与えたくないのですが、次に実行されるタスクは、私が指定したタスクになります。方法の例を以下に示します。どうすればよいですか?

ありがとう

private ExecutorService singleLoadPool = Executors.newSingleThreadExecutor();
public void submitTask(Runnable run, boolean doNow) {
    if (doNow)
        singleLoadPool.submitFront(run);  // This is the method I'm looking for
    else
        singleLoadPool.submit(run);
}
4

2 に答える 2

4

私の好みはを使用することLinkedBlockingDequeです。位置の挿入/削除を直接サポートします-putFirst(e)/takeFirst()そしてputLast(e)/takeLast()-これはあなたの主な要件です-あなたはComparatorあなたの要素のためにを実装する必要はありません。また、これには制限があります。つまり、に対する安全性が提供されますOutOfMemoryError

編集最新の質問に答えて:

まず、ExecutorServiceを次のようにします

ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);

第二に、重要な質問は:何workQueueですか?

は、任意の実装workQueueの薄いラッパーであり、次のように、によって呼び出され、オーバーライドする必要があるメソッドを除いて、すべてのメソッドをそれが含むインスタンスに委任します。BlockingQueueLinkedBlockingDequeoffer()ThreadPoolExecutor

       public boolean offer(E e) {
       if(doNow)
         return linkedBlockingDequeInstance.offerFirst(e);
      else 
         return linkedBlockingDequeInstance.offerLast(e);
   }

もちろん、メソッドをオーバーライドするときは、スレッドの安全性とその一般的な契約を維持するように注意する必要があります。これには、慎重な検討と厳密なテストが必要です。

于 2012-08-01T20:37:19.390 に答える
1

これに対する最善のアプローチは、をでインスタンス化するThreadPoolExecutorことだと思いますPriorityBlockingQueue。具体的には、を取り込むPriorityBlockingQueueコンストラクターを使用しますComparator。あなたComparatorはあなたがあなたの「優先順位」を実行するために使用するものになります。

PriorityBlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<Runnable>(20, yourPriorityComparator);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
于 2012-08-01T19:58:58.717 に答える