2017-04-03 4 views
1

私は、Javaで多数のシリアルディスパッチキューを管理する必要があります。それぞれが独自の実行ループを管理するために必要なエンジンモジュールがいくつかあります(そのうちのいくつかは非常に迅速に完了し、他のモジュールは長期間ブロックされる可能性があります)。各エンジンに提出されたジョブは、順番に実行する必要があります。ExecutorsをJavaで使用するシリアルディスパッチキュー?

理想的には、各エンジンにはスレッドが0から1の間でスケーリングされる単一のスレッドプールがあり、数百ものイベントが発生した場合、ExecutorServiceはシリアルとなり、 。

しかし、私はいずれかを使用しようとしたとき:

new ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>()); 

または

new ThreadPoolExecutor(1, 1, 30L, TimeUnit.SECONDS, new SynchronousQueue<>()); 

私は(最初のジョブがまだ実行されている場合)は、第2のジョブが送信されたときにRejectedExecutionExceptionがあることがわかり

スローされた、私は2つのジョブを実行する1つのスレッドを持っていると仮定し、executorはそれを気に入らない。

これを独自のキューで実装して、オンデマンドで自分のThreadインスタンスを開始/停止/破棄することができますが、これはExecutorが行うことができるようなものです。

キャッシュされたスレッドプールを作成する方法(またはExecutorの実装)はありますか?ジョブがなくても期限切れになり、終了することができます。

答えて

1

ドキュメントが言及してあなたの特定の問題は、SynchronousQueueの使用から来る:

同期キューは、任意の内部容量、1のもない能力を持っていません。

これをLinkedBlockingQueueに置き換えると、実際に動作します。

しかし、に関する実行者は、タスクを実行するために上位1つのスレッドで使用するので、Executors.newSingleThreadExecutorです。

簡単な例:

public static void main(String[] args) 
{ 
    ExecutorService executor = Executors.newFixedThreadPool(1); 
    TestThread t1 = new TestThread(1); 
    TestThread t2 = new TestThread(2); 
    executor.submit(t1); 
    Future<?> f2 = executor.submit(t2); 
    try { 
     f2.get(); 
    } catch (InterruptedException | ExecutionException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    ThreadPoolExecutor tt = (ThreadPoolExecutor) executor; 
    System.out.println(tt.getActiveCount()); //ensuring that there is no active threads in the pool after last thread terminates 
} 

public static class TestThread implements Runnable{ 
    private int id; 

    public TestThread(int num){ 
     id = num; 
    } 
    public void run() { 
     System.out.println("running thread: " + id); 
     try { 
      Thread.sleep(2000); 
      System.out.println("After sleeping thread " + id); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

} 

は、予想される出力を提供します:

running thread: 1 
After sleeping thread 1 
running thread: 2 
After sleeping thread 2 
0 

終了し、最後の1の後にはアクティブなスレッドがありません。

関連する問題