ThreadPoolExecutor Block When Queue Is Full?

前端 未结 8 1828
无人及你
无人及你 2020-11-29 17:42

I am trying to execute lots of tasks using a ThreadPoolExecutor. Below is a hypothetical example:

def workQueue = new ArrayBlockingQueue(3, f         


        
8条回答
  •  隐瞒了意图╮
    2020-11-29 18:04

    I solved this problem using a custom RejectedExecutionHandler, which simply blocks the calling thread for a little while and then tries to submit the task again:

    public class BlockWhenQueueFull implements RejectedExecutionHandler {
    
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
    
            // The pool is full. Wait, then try again.
            try {
                long waitMs = 250;
                Thread.sleep(waitMs);
            } catch (InterruptedException interruptedException) {}
    
            executor.execute(r);
        }
    }
    

    This class can just be used in the thread-pool executor as a RejectedExecutionHandler like any other. In this example:

    executorPool = new def threadPoolExecutor = new ThreadPoolExecutor(3, 3, 1L, TimeUnit.HOURS, workQueue, new BlockWhenQueueFull())
    

    The only downside I see is that the calling thread might get locked slightly longer than strictly necessary (up to 250ms). For many short-running tasks, perhaps decrease the wait-time to 10ms or so. Moreover, since this executor is effectively being called recursively, very long waits for a thread to become available (hours) might result in a stack overflow.

    Nevertheless, I personally like this method. It's compact, easy to understand, and works well. Am I missing anything important?

提交回复
热议问题