Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java是否有可索引的多队列线程池?_Java_Multithreading_Queue_Threadpool - Fatal编程技术网

Java是否有可索引的多队列线程池?

Java是否有可索引的多队列线程池?,java,multithreading,queue,threadpool,Java,Multithreading,Queue,Threadpool,是否存在这样的Java类: 可执行任务可以通过id添加,其中具有相同id的所有任务都保证不会并发运行 线程的数量可以限制为固定数量 简单的地图解决方案很容易解决(1),但很难管理(2)。类似地,我所知道的所有线程池类都将从单个队列中提取,这意味着(1)不能得到保证 欢迎使用涉及外部库的解决方案。如果您没有找到现成的解决方案,那么您自己的解决方案应该不难。您可以做的一件事是将每个任务包装在一个简单的类中,该类读取每个id唯一的队列,例如: public static class SerialCal

是否存在这样的Java类:

  • 可执行任务可以通过id添加,其中具有相同id的所有任务都保证不会并发运行
  • 线程的数量可以限制为固定数量
  • 简单的地图解决方案很容易解决(1),但很难管理(2)。类似地,我所知道的所有线程池类都将从单个队列中提取,这意味着(1)不能得到保证


    欢迎使用涉及外部库的解决方案。

    如果您没有找到现成的解决方案,那么您自己的解决方案应该不难。您可以做的一件事是将每个任务包装在一个简单的类中,该类读取每个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();
        }
    }
    
    公共静态类SerialCaller实现可调用{
    私有最终阻止队列代理;
    public SerialCaller(阻止队列委托){
    这个。代表=代表;
    }
    public T call()引发异常{
    返回委托。take().call();
    }
    }
    

    维护ID到提交任务队列的映射应该很容易。它满足条件(1),然后您可以寻找条件(2)的简单解决方案,例如

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


    使用更复杂的解决方案可以实现的唯一一件事是使用更少的线程,但如果索引的数量很小且有界,则可能不值得这样做。

    对于每个id,您需要一个SerialExecutor,如的文档中所述。所有串行执行器都将工作委托给具有给定corePoolSize的


    SerialExecutor的优化版本可在上找到。

    是的,现在有这样一个库:

    intmaxstasks=10;
    ExecutorService underyingExecutor=Executors.newFixedThreadPool(maxTasks);
    KeySequentialBoundedExecutor executor=新的KeySequentialBoundedExecutor(maxTasks,UnderlineExecutor);
    Runnable任务=新的Runnable(){
    @凌驾
    公开募捐{
    //做点什么
    }
    };
    executor.execute(新的KeyRunnable(“ID-1”,task));//由底层执行者执行任务
    executor.execute(新的KeyRunnable(“ID-2”,task));//ID-1的任务未阻止执行
    executor.execute(新的KeyRunnable(“ID-1”,task));//ID-1的上一个任务完成时开始执行
    
    @Makky,我一直在特别关注SpringTaskExecutor@downvoters,为什么这个问题不好?这不是一个“plz给我代码”的问题,在我看来,这将是多线程的一个相当常见的用例,谷歌搜索并没有产生任何明显的结果。您最初的建议似乎更轻,更容易实现-有什么原因可以改变吗?@Assylas我意识到这可能是一个很大的瓶颈。假设您的线程池也被限制为N个线程,并且在id A下有N个任务,在id B和C下也有一些任务。不幸的是,A的所有任务都得到了调度。这意味着N-1个线程被阻止——并且没有执行B或C的任务。请添加有关将ID映射到队列以及提交和轮询任务的源代码,以完成此回答。这是Java文档中隐藏的宝石!SerialExecutor有效地实现了一个多队列线程池,但它们并没有真正做到这一点。@Alexei Kaigorodov,在您安排好github repo后,旧答案中的一些链接最终变成了404-从昨天开始,我遇到了两种不同的情况。我猜这里提到的是,但如果你有机会,请尝试修复它们。谢谢