Executors.new*
(e.g. you're constructing your own instances of ThreadPoolExecutor
) and you're using LinkedBlockingQueue
so that you can build up a task list, be aware that ThreadPoolExecutor
got completely rewritten in Java 6.Under Java 5, the behavior is that if you set the core size of the thread pool to 0 threads, then the pool won't actually kick off a single thread until the
offer
method on your BlockingQueue
refuses a new element. In the case of LinkedBlockingQueue
, that means that it won't kick off a thread until you've reached the maximum number of elements in your queue (the number in the constructor that you are obviously specifying to a reasonable number for your workload), which isn't quite what you would expect.The workaround is to set your core size to >= 1, or to just use Java 6, which doesn't have this behavior (the
execute(Runnable)
method was rewritten and has special logic if the pool size is 0 to force it to create a new Thread
in that case). In general, though, setting the core size to at least 1 is always a safe thing to do and will work across both Java versions.Yes, this did bite me. And yes, thanks to continuous integration checking JVMs that my coworkers insist on using but which I abandoned years ago, I tracked this down to precisely this problem. Updated 2009-06-25: Got corrected in a comment that I said
SynchronousQueue
when I should have said BlockingQueue
.