当前位置: 首页 > 知识库问答 >
问题:

ExecutorService可扩展线程,然后对任务进行排队

曾光远
2023-03-14

是否有一个ExecutorService实现,其行为类似具有以下特性的线程池?

  1. 始终至少有X个活动线程。

相当标准的线程池行为。你可能会认为ThreadPoolExecator可以处理这个问题,但是

executorService = new ThreadPoolExecutor(
    2, 10, // min/max threads
    60, TimeUnit.SECONDS, // time of inactivity before scaling back
    new SynchronousQueue<Runnable>()); // task queue

如果提交了10个以上的任务,将引发异常。切换到LinkedBlockingQueue永远不会超过两个最小线程,除非您限制像new LinkedBlockingQueue这样的大小


共有3个答案

狄法
2023-03-14

这应该可以做到:

    ThreadPoolExecutor tpe = new ThreadPoolExecutor(1, maxPoolSize, 60L, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>());
    tpe.setRejectedExecutionHandler((
            Runnable r,
            ThreadPoolExecutor executor) -> {
        // this will block if the queue is full but not until the sun will rise in the west!
            try {
                if(!executor.getQueue().offer(r, 15, TimeUnit.MINUTES)){
                    throw new RejectedExecutionException("Will not wait infinitely for offer runnable to ThreadPoolExecutor");
                }
            } catch (InterruptedException e) {
                throw new RejectedExecutionException("Unable to put runnable to queue", e);
            }
        });
范浩荡
2023-03-14

实际上,同步队列的大小基本上为零,因此,当您提交超过10个任务(最大池大小)时,拒绝策略会启动,任务会被拒绝。此外,对于每个提交的任务,它都会获得一个线程并加以利用。

当您使用大小为20的LinkedBlockingQueue时,如果已达到核心大小且没有空闲线程,它将对任务进行排队。除非队列已满,否则它们将继续排队,在这种情况下,它将创建一个用于新任务的新线程。当池大小达到最大值时,拒绝策略将用于任何新提交。

您希望每当提交任务时,核心(core-size)中的所有线程都很忙,您的任务应该获得一个新的线程,而不是在队列中等待,我认为这是不可能的。

毛勇
2023-03-14

不幸的是,答案是否定的。对于jre中的内容,你能做的最好的事情就是有效地没有Thread底板,只有天花板。这可以通过允许核心线程超时来实现。

ThreadPoolExecutor tpe = new ThreadPoolExecutor(10, 10, 60, TimeUnit.Seconds, new LinkedBlockingQueue<Runnable>());
tpe.allowCoreThreadTimeOut(true);

因为核心大小为10,所以在提交任务时会启动一个新线程,直到10个线程处于活动状态。之后,任务将在LinkedBlockingQueue中排队。如果一个线程处于非活动状态60秒,它将终止。

通过编写一个同时实现BlockingQueue和RejectedExecutionHandler的类,可以实现您想要的行为,该类在确定任务是否应添加到队列或被拒绝之前检查ThreadPoolExecutors的当前状态。

 类似资料:
  • 问题内容: 为什么实现Runnable比从Thread类扩展更好的选择? 问题答案: 这样,您就可以 将 计算( what )与执行( when 和/或 how )分离。 使用或,您可以例如向提交许多工作/计算,这将使您计划工作。这是ExecutorService的摘录形式: 与直接使用线程相比,使用/ 给您更大的灵活性。

  • 我使用JavaFX制作了一个GUI,有三个单选按钮,一旦用户单击提交并创建了另一个线程,并且根据检查了什么单选按钮,线程运行所需的输出并将结果输出到控制台。 但是当线程运行时(一个进程需要大约30秒才能完成),我可以检查任何放射性按钮。它创建另一个线程并与另一个正在进行的线程一起输出长时间。所以我的输出框只是一个乱七八糟的东西!我在看异步任务,但我不确定这是否与它有关。 以下是我需要的:如果一个任

  • JavaExecutorService框架允许您使用托管线程池委托要执行的多个任务,以便一次可以执行N个任务X个任务,直到完成。 我的问题是。。。如果N是一个无限大的数字,或者太大以至于最初无法分配/分配/定义,该怎么办。 如何利用Java(ExecutorService)中的线程池概念来处理比合理提交更多的任务,而不会耗尽资源。 为了回答这个问题,假设每个任务都是自包含的,不依赖于任何其他任务,

  • 更新了问题和图像。 是否有任何方法可以暂停所有线程,直到任何线程执行samplerA为止(不管线程数是多少,这只需要执行一次),在执行这个sampler之后,所有线程都可以继续执行。单击以获取图像