Executors.new*(e.g. you're constructing your own instances of
ThreadPoolExecutor) and you're using
LinkedBlockingQueueso that you can build up a task list, be aware that
ThreadPoolExecutorgot 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
offermethod on your
BlockingQueuerefuses 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
Threadin 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
SynchronousQueuewhen I should have said