我试图用一个ThreadPoolExecutor安排任务,但是遇到了一些问题有它的政策。这里的其声明的行为:

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

该行为的我想是这样的:

  1. 上述相同
  2. 如果超过corePoolSize但小于maximumPoolSize线运行、更加一个新的螺纹在排队,并利用闲置的线上增加一个新的螺纹。
  3. 上述相同

基本上我不想要任何的任务予以驳斥;我想让他们排队在一个无边界的队列。但我希望有多达maximumPoolSize线。如果我使用一个无边界的队列,它永远不会产生螺纹后它撞coreSize.如果我使用一个有界限的队列,它拒绝接受任务。是否有任何办法解决这个?

什么我想现在正在运行的ThreadPoolExecutor在SynchronousQueue,但不是喂的任务直接到它-代替喂养他们对一个独立的无限LinkedBlockingQueue.然后另外一个线程的饲料,从LinkedBlockingQueue成为遗嘱执行人,如果一个人被拒绝,这只是尝试一次,直到它不是拒绝。这似乎是一个痛苦和一点的一个黑客,但是有一个更清洁的方式来做到这个吗?

有帮助吗?

解决方案

你使用的情况下是共同的,完全合法的和不幸的是比较困难的,而不是一个希望。为背景信息,你可以读 这次讨论 并找到一个指向一个解决方案(还提到在线) 在这里,.谢伊的解决方案。

一般我是有点担心无限的队列;它通常更好地有明确的进入流的控制,缓慢下降,并规定比目前的/剩余的工作不会压倒无论是生产者或消费者。

其他提示

它可能是不必要进行微观管理该线的游泳池作为被请求。

缓存线的游泳池将重新利用闲置的线,同时也允许可能是无限的并发线程。这当然可能会导致失控的性能有辱人格的待从上下文交换的开销在突发的周期。

Executors.newCachedThreadPool();

一个更好的选择是将一种限制在线程总数,同时抛弃这一概念确保空闲线用的第一个。配置变化将是:

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

推理过这种情况下,如果遗嘱执行人有不到 corePoolSize 线,比它不能非常繁忙。如果系统是不是很忙,再有就是小小的伤害,在纺立一个新的螺纹。这样做将会导致你的 ThreadPoolExecutor 总是创建一个新的工作人员,如果它是根据最大数量的工人,允许的。只有当最大数量的工人"运行的"将工作人员在等待袖手旁观的任务被赋予的任务。如果工作人员等待 aReasonableTimeDuration 没有一个任务,那么它是允许终止。采用合理的限制游泳池尺寸(毕竟,只有如此多的Cpu)和一个相当大的超时(保留的线从不必要地终止),所需的好处可能会被看到。

最终的选择是予以解决了.基本上, ThreadPoolExecutor 在内部使用 BlockingQueue.offer 确定如果队有能力。一个自定义的执行情况 BlockingQueue 总是可以拒绝 offer 尝试。时 ThreadPoolExecutor 失败 offer 任务的队列,它将试图使一个新的工作人员。如果一个新的工作人员不能创建一个 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
}

刚刚成立 corePoolsize = maximumPoolSize 和使用无限队?

在你的名单分,1不包括2,因为 corePoolSize 总会小于或等于 maximumPoolSize.

编辑

仍然有一些不兼容之间有什么你想要什么材料将提供给你。

如果你有一个无限的队列, maximumPoolSize 被忽略,所以,因为你观察到,没有超过 corePoolSize 线都不会是创造和使用。

因此,再次,如果你采取 corePoolsize = maximumPoolSize 一个无限的队列,你有你想要什么,不是吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top