2011-08-31 83 views
1

我有一个ThreadPoolExecutor是用一个无界队列(LinkedBlockingQueue)和一个核心和最大池大小设置为cpus数(比如说4)构造的。我不明白这个ThreadPoolExecutor行为

每当我得到一个RejectedExecutionException异常。执行器处于运行状态。我的理解是,这不应该发生在无边界的队列中。

我一直没有能够在调试器中看到发生了什么,但是从堆栈跟踪看起来像在ThreadPoolExecutor.execute中,workQueue.offer返回false,所以它跳转到位它试图启动一个新的线程。但是poolSize已经在最大值,所以它会抛出被拒绝的执行异常。

我不太明白这一点。

但是无论如何,我是否应该使最大池大小比核心池大小大一点?

+1

看看这个优秀的答案,并upvote它:http://stackoverflow.com/questions/1800317/impossible-to-make-a-cached-thread-pool-with-a-size-limit/1800583# 1800583 –

+2

这个答案只是证实@deliciousirony看到的行为不应该发生。 – Thilo

+0

你可以发表一些代码吗? – jiggy

回答

2

LinkedBlockingQueue.offer()返回false当它在其容量。如果容量未指定,则使用Integer.MAX_VALUE

添加2147483647个任务多于您的池大小时会发生这种情况吗?

+0

是的,我们可能正在排队。我不认为这是可能的,但现在我是。没有别的东西会有意义。谢谢。 – marathon

2
  1. 即使是“无界的”LinkedBlockingQueue实际上也是bounded at Integer.MAX_VALUE。是的,你不可能达到这个限度,但是“一旦你消除了不可能......”。
  2. 你有多确定执行者仍处于RUNNING状态?在我的源代码中,状态检查和offer()调用都位于同一行,因此您无法在堆栈跟踪中区分它们。
+0

虽然我同意非RUNNING状态会这样做,但带状态检查和offer()调用的行根本不在堆栈跟踪中。堆栈跟踪将包含拒绝(命令)行。 –

+0

我开始认为我们实际上正在排队。这个应用程序运行在64位虚拟机上,并提供几乎无限的内存。负载是巨大的,如果工作人员因任何原因而停滞不前,我们可能会在几个小时内填补这个队列。我要检查LinkedBlockingQueue,看看是否是这样。谢谢。 – marathon