gpt4 book ai didi

java - ThreadPoolExecutor 政策

转载 作者:搜寻专家 更新时间:2023-10-30 20:02:21 28 4
gpt4 key购买 nike

我正在尝试使用 ThreadPoolExecutor 来安排任务,但在其策略方面遇到了一些问题。这是其声明的行为:

  1. 如果运行的线程少于 corePoolSize,执行器总是倾向于添加新线程而不是排队。
  2. 如果 corePoolSize 或更多线程正在运行,则执行器总是更喜欢排队请求而不是添加新线程。
  3. 如果请求无法排队,则会创建一个新线程,除非这会超过 maximumPoolSize,在这种情况下,任务将被拒绝。

我想要的行为是这样的:

  1. 同上
  2. 如果有超过 corePoolSize 但少于 maximumPoolSize 的线程在运行,则优先添加新线程而不是排队,使用空闲线程而不是添加新线程。
  3. 同上

基本上我不希望任何任务被拒绝;我希望他们在无界队列中排队。但我确实希望拥有最多 maximumPoolSize 线程。如果我使用无界队列,它在达到 coreSize 后永远不会生成线程。如果我使用有界队列,它会拒绝任务。有什么办法解决这个问题吗?

我现在考虑的是在 SynchronousQueue 上运行 ThreadPoolExecutor,但不是直接向它提供任务 - 而是将它们提供给一个单独的无界 LinkedBlockingQueue。然后另一个线程从 LinkedBlockingQueue 进入 Executor,如果一个线程被拒绝,它会再次尝试直到没有被拒绝。不过,这似乎很痛苦,而且有点麻烦 - 有没有更简洁的方法来做到这一点?

最佳答案

可能没有必要根据请求对线程池进行微观管理。

缓存线程池将重新使用空闲线程,同时还允许潜在的无限并发线程。这当然会导致突发期间上下文切换开销导致性能失控。

Executors.newCachedThreadPool();

更好的选择是对线程总数进行限制,同时放弃确保首先使用空闲线程的概念。配置更改为:

corePoolSize = maximumPoolSize = N;
allowCoreThreadTimeOut(true);
setKeepAliveTime(aReasonableTimeDuration, TimeUnit.SECONDS);

根据这种情况推理,如果执行程序的线程少于 corePoolSize,那么它一定不会很忙。如果系统不是很忙,那么启动一个新线程也没什么坏处。这样做会导致您的 ThreadPoolExecutor 在低于允许的最大工作人员数量时始终创建一个新工作人员。只有当最大数量的worker在“运行”时,才会给空闲等待任务的worker分配任务。如果工作人员在没有任务的情况下等待 aReasonableTimeDuration,则允许终止。对池大小使用合理的限制(毕竟,只有这么多 CPU)和相当大的超时(以防止线程不必要地终止),可能会看到预期的好处。

最后一个选项是骇人听闻的。基本上,ThreadPoolExecutor 在内部使用 BlockingQueue.offer 来确定队列是否有容量。 BlockingQueue 的自定义实现总是可以拒绝 offer 尝试。当 ThreadPoolExecutor 无法向队列提供 任务时,它将尝试创建一个新的 worker。如果无法创建新的 worker,则会调用 RejectedExecutionHandler。此时,自定义 RejectedExecutionHandler 可以强制将 put 放入自定义 BlockingQueue

/** Hackish BlockingQueue Implementation tightly coupled to ThreadPoolexecutor implementation details. */
class ThreadPoolHackyBlockingQueue<T> implements BlockingQueue<T>, RejectedExecutionHandler {
BlockingQueue<T> delegate;

public boolean offer(T item) {
return false;
}

public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
delegate.put(r);
}

//.... delegate methods
}

关于java - ThreadPoolExecutor 政策,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3419380/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com