2013-07-31 49 views
6

是否有一个Java类这样的:Java是否有可索引的多队列线程池?

  1. 可执行的任务可以通过一个ID,其中用相同的ID的所有任务都保证永远不会同时运行
  2. 线程的数量可以被限制在一个可以添加固定金额

一个天真的解决方案的地图很容易解决(1),但它会很难管理(2)。同样,我知道的所有线程池类都将从单个队列中提取,这意味着(1)不能保证。

欢迎提供涉及外部库的解决方案。

+0

你试过了什么? – Makky

+0

@Makky,我一直专注于Spring TaskExecutor – 00500005

+2

@downvoters,为什么这是一个坏问题?这不是一个“plz给我这个代码”的问题,在我看来,这对于多线程来说是一个相当常见的用例,并且使用google搜索不会产生任何明显的结果 – 00500005

回答

3

如果您找不到可以开箱即用的东西,则不应该很难推出自己的产品。有一两件事你可以做的是包装每个任务的简单类每ID唯一一个队列中读取,例如:

public static class SerialCaller<T> implements Callable<T> { 
    private final BlockingQueue<Caller<T>> delegates; 

    public SerialCaller(BLockingQueue<Caller<T>> delegates) { 
     this.delegates = delegates; 
    } 

    public T call() throws Exception { 
     return delegates.take().call(); 
    } 
} 

它应该是易于维护地图ID到队列中提交的任务。这满足条件(1),然后你可以寻找简单的解决方案条件(2),如Executors. newFixedThreadPool

+0

您的初始建议看起来更轻松,更易于实现 - 任何改变的原因? – assylias

+1

@assylias我意识到它可能是一个很大的瓶颈。假设您的线程池也限制为N个线程,并且您在ID A下有N个任务,并且在ID B和C下有一些数字。通过不幸的巧合,A的所有任务都会按计划进行。这意味着N-1线程被阻塞 - 并且不执行B或C的任务。 – yshavit

+0

请问您可以通过添加有关将ID映射到队列以及提交和轮询任务的源代码来完成此答案? – Mojtabye

2

我认为最简单的解决方案是为每个索引和一个单独的执行器(与每个队列有一个线程)。

你可以用更复杂的解决方案实现的唯一的事情就是使用更少的线程,但是如果索引的数量很小并且有界,那可能是不值得的。

2

对于每个ID,您需要一个SerialExecutor,在文档java.util.concurrent.Executor中描述。所有的串行执行者都将工作委托给具有给定corePoolSize的ThreadPoolExecutor

可以在my code samples找到最优化的SerialExecutor版本。

+0

这是Java文档中隐藏的宝石! SerialExecutor有效地实现了一个多队列线程池,但他们并没有真正做到这一点。 – blueimpb