no blocking feature in ThreadPoolExecutor

A known issue — The Sun bugs database http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6648211 describes the unexpected immediate-failure behavior of blocking-thread-pool, and mentions a Spring forum discussion —

“You have to modify the java.util.concurrent.ThreadPoolExecutor by overriding the execute method and place a task with a put instead of an offer with a zero timeout on the workqueue. Or you could use the BlockingExecutor (and the ThreadPoolBlockingExecutor) from Prometheus. The primary reason of existence of these classes was to create an Executor that is able to block.”

JDK ThreadPoolExector javadoc made it clear — “New tasks submitted in method ThreadPoolExecutor.execute will be rejected when the Executor … uses finite bounds for work queue capacity, and is saturated.” Root cause beneath the non-blocking behavior of blocking-queue is the use of queue.offer(). “Offer” sounds like “try inserting” and therefore non-blocking. It returns false if queue full. In contrast, the put() method is blocking.

   public void execute(Runnable command) {
       if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
           if (runState == RUNNING && workQueue.offer(command)) {

Personal experience #1 — we created a simple blocking thread pool. Avoid ThreadPoolExecutor.execute(). Manually create an array blocking queue of fixed capacity, and add tasks using put().

Personal experienc #2 — An even simpler solution is a “shared unbounded queue” (see javadoc) free of blocking altogether —

     virtThrPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(howManyThreads);

(You don’t have to cast, but casting gives many convenient methods of ThreadPoolExecutor.java)

You can easily submit() tasks and never get blocking or rejection.

留下评论