【发布时间】:2019-04-13 16:24:14
【问题描述】:
我正在为 Spring Boot 应用程序中生成的消息的消费者使用固定线程池。我的生产者的生产速度(比生产者处理消息的速度快很多),因此线程池的队列似乎“泛滥”。
限制队列大小的最佳方法是什么?预期的队列行为将是“如果队列已满,则移除头部并插入新的 Runnable”。可以这样配置Executors线程池吗?
【问题讨论】:
标签: java multithreading queue threadpoolexecutor
我正在为 Spring Boot 应用程序中生成的消息的消费者使用固定线程池。我的生产者的生产速度(比生产者处理消息的速度快很多),因此线程池的队列似乎“泛滥”。
限制队列大小的最佳方法是什么?预期的队列行为将是“如果队列已满,则移除头部并插入新的 Runnable”。可以这样配置Executors线程池吗?
【问题讨论】:
标签: java multithreading queue threadpoolexecutor
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);
【讨论】:
这将为您创建一个您传递的大小的线程池。
ExecutorService service = Executors.newFixedThreadPool(THREAD_SIZE);
这在内部创建了一个实现 ExecutorService 的 ThreadPoolExecutor 实例。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
要创建自定义主题池,您可以这样做。
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);
}
希望这会有所帮助。干杯!!!
【讨论】: