1

特定の数のスレッドでThreadPoolExecutorを作成しようとしていますが、同時に、プールキューのサイズを制御したいと思います。そこで、完全なコンストラクターを使用してエグゼキューターを作成しました。

 BlockingQueue<Runnable> pq =
     new ArrayBlockingQueue<Runnable>(MAX_THREADPOOL_SIZE);
 ThreadPoolExecutor threadPoolExecutor =
     new ThreadPoolExecutor(threadSize, threadSize, THREAD_IDLE_WAIT,
          TimeUnit.SECONDS, pq);

しかし、これは私にを与えますIllegalArgumentException。コンストラクターをに変更した場合

new ThreadPoolExecutor(threadSize, **threadSize+1**, THREAD_IDLE_WAIT,
     TimeUnit.SECONDS, pq);

できます。理想的なスレッド数と最大スレッド数を同じにしたいのに、なぜ機能しないのでしょうか。

4

3 に答える 3

4

javadocから:corePoolSize、keepAliveTimeがゼロ未満の場合、maximumPoolSizeがゼロ以下の場合、またはcorePoolSizeがmaximumPoolSizeより大きい場合。したがって、それらは等しくなることもできます。私も同じ値で構築しようとしましたが、うまくいきました。たぶん、ソースコードはあなたが問題が何であるかを見つけるのを助けることができます:

if (corePoolSize < 0 ||
    maximumPoolSize <= 0 ||
    maximumPoolSize < corePoolSize ||
    keepAliveTime < 0)
    throw new IllegalArgumentException();
于 2012-08-09T16:48:49.850 に答える
0

最初のコードがスローされるべきだった理由はわかりません。将来、完全な例外を提供する場合は、より具体的なヘルプを提供できます。

覚えておくべきことの1つはBlockingQueue、キューがいっぱいになると、境界を使用すると例外がスローされることです。これはめったにあなたが期待するものではありません。次の質問に対する私の答えを見ると、RejectedExecutionHandler:を構成する必要があることがわかります。

処理する必要のあるデータが多すぎる場合、ThreadPoolExecutorコマンドを待機させるにはどうすればよいですか?

そこからコピーするには、次のようなことを行う必要があります。

final BlockingQueue queue = new ArrayBlockingQueue<Runnable>(200);
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(nThreads, nThreads,
           0L, TimeUnit.MILLISECONDS, queue);
// by default (unfortunately) the ThreadPoolExecutor will throw an exception
// when you submit the 201st job, to have it block you do:
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
   public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
      // this will block if the queue is full
      executor.getQueue().put(r);
   }
});

最後に、最大スレッドサイズがコアスレッドサイズよりも大きい場合は、コアサイズを超える追加のスレッドが割り当てられる前にキューがいっぱいになることを認識しておく必要があります。奇妙ですが本当です。

于 2012-08-09T18:07:10.090 に答える
-1

代わりに、一定数のスレッドに対してファクトリメソッドを使用してください。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int

次に、必要に応じてタイムアウトを設定します。

ThreadPoolExecutor exec = (ThreadPoolExecutor)Executors.newFixedThreadPool(threadSize);
exec.setKeepAliveTime(THREAD_IDLE_WAIT, TimeUnit.SECONDS);
于 2012-08-09T16:37:21.777 に答える