ThreadPoolExecutor有限的线程数

时间:2012-08-09 16:33:49

标签: java multithreading

我正在尝试创建一个具有一定数量线程的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);

它有效。如果我希望理想线程和最大线程数相同,为什么它不会工作。

3 个答案:

答案 0 :(得分:4)

来自javadoc:如果corePoolSize或keepAliveTime小于零,或者maximumPoolSize小于或等于零,或者 corePoolSize大于maximumPoolSize 。所以他们也可以是平等的。我也尝试用相同的值构建它并且它有效。也许源代码可以帮助您找出问题所在:

if (corePoolSize < 0 ||
    maximumPoolSize <= 0 ||
    maximumPoolSize < corePoolSize ||
    keepAliveTime < 0)
    throw new IllegalArgumentException();

答案 1 :(得分:0)

我认为你的初始代码没有理由抛出。如果您将来提供完整例外,我们可以提供更具体的帮助。

要记住的一件事是,一旦队列满了,使用有界BlockingQueue将抛出异常。这很少是你所期望的。如果您查看我对以下问题的回答,您会看到需要配置RejectedExecutionHandler

  

How can I make ThreadPoolExecutor command wait if there's too much data it needs to work on?

要从那里复制,您需要执行以下操作:

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);
   }
});

最后,如果你的最大线程大小大于核心线程大小,你必须意识到队列将在之前填充,然后分配核心大小的任何其他线程。奇怪但真实。

答案 2 :(得分:-1)

使用factory方法代替常量线程。

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);