执行程序线程池-限制队列大小和最早的出队

时间:2018-11-10 07:30:28

标签: java multithreading queue threadpoolexecutor

我在Spring Boot应用程序中使用固定线程池来处理产生的消息。我的生产者的生产速度比生产者处理消息的速度快很多,因此线程池的队列似乎“泛滥”。

限制队列大小的最佳方法是什么?预期的队列行为将是“如果队列已满,请除去头部并插入新的Runnable”。这样可以配置执行程序线程池吗?

2 个答案:

答案 0 :(得分:2)

ThreadPoolExecutor通过ThreadPoolExecutor.DiscardOldestPolicy支持此功能:

  

用于拒绝任务的处理程序,它丢弃最早的未处理程序   请求,然后重试执行,除非执行器被关闭,否则   在这种情况下,任务将被丢弃。

例如,您需要手动使用此策略来构造池:

int poolSize = ...;
int queueSize = ...;
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();

ExecutorService executorService = new ThreadPoolExecutor(poolSize, poolSize,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<>(queueSize),
    handler);

答案 1 :(得分:1)

这将为您创建一个与您通过的大小相同的线程池。

ExecutorService service = Executors.newFixedThreadPool(THREAD_SIZE);

这在内部创建ThreadPoolExecutor的实例,该实例实现ExecutorService。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

只需创建一个自定义thead池即可。

ExecutorService service =   new ThreadPoolExecutor(5, 5,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(10));

在这里,我们可以使用LinkedBlockingQueue的重载构造函数指定队列的大小。

    public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

希望这会有所帮助。干杯!!!