java - 执行器服务的所有线程都在处理任务时,是否可以等待主线程

标签 java multithreading executorservice

我有一个场景,将数百万数据插入后端,并且当前使用执行器框架来加载它。我会用更简单的术语解释我的问题。

在下面的情况下,我有 10 个可运行的线程和三个线程来执行相同的操作。考虑我的 runnable 正在执行插入操作,并且需要时间才能完成任务。当我检查时,了解到,如果所有线程都忙,其他任务将进入队列,一旦线程完成任务,它将从池中获取任务并完成它。

因此,在这种情况下,将创建 SampleRunnable 4 到 10 的对象,并且该对象将位于池中。

问题:由于我需要加载数百万个任务,因此我无法加载队列中的所有记录,这可能会导致内存问题。所以我的问题是,是否可以让主线程等待,直到任何一个执行器工作线程变得可用,而不是获取队列中的所有任务。

我尝试使用以下方法作为解决方法,而不是排队这么多任务:

方法 1:使用数组阻塞队列作为执行器,并将大小指定为 5(例如) 因此,在这种情况下,当第 9 个任务到来时,这将抛出 RejectedExecutionException 并在 catch 子句中, hibernate 1 分钟并递归地尝试相同的操作。当线程可用时,这将在任何重试中被拾取。

方法2:使用关闭并等待终止。即,如果任务计数为 5,我将关闭并等待终止。在await Termination 'if' block (executor.awaitTermination(60000,TimeUnit.SECONDS))中,我再次实例化线程池。


public class SampleMain {

public static void main(String[] args) {

ExecutorService executor = Executors.newFixedThreadPool(3);

for (int i=0;i<10;i++){ 
   executorService.execute(new SampleRunnable(i));
}

executor.shutdown();
}

最佳答案

听起来问题是,您想要限制主线程,以便它不会领先于工作人员。如果是这种情况,请考虑显式构造 ThreadPoolExecutor 实例,而不是调用 Executors.newFixedThreadPool()

该类有几个不同的构造函数,其中大多数允许您提供自己的阻塞队列。如果您创建一个大小有限的ArrayBlockingQueue,那么每次队列变满时,主线程都会自动阻塞,直到工作人员通过执行另一个任务来腾出空间。

final int work_queue_size = 30;
BlockingQueue work_queue = new ArrayBlockingQueue(work_queue_size);
ExecutorService executor = new ThreadPoolExecutor(..., work_queue);

for (int i=0;i<10;i++){ 
    executorService.execute(new SampleRunnable(i));
}
...

关于java - 执行器服务的所有线程都在处理任务时,是否可以等待主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58453620/

相关文章:

java - 终止并向 Executor 提交可调用对象

java - 关于ExecutorService的澄清

java - 在大 map 中按降序查找前 20 个值

java - 如何在 Gradle 中生成元模型?

java - ExecutorService(int n) 和 Thread.activeCount() 是如何工作的?

c# - Process.OutputDataReceived 在哪个线程上引发和处理?

iphone - 从后台线程访问实例变量

java - Jooq 按日/月/年比较时间戳

java - 在Spring应用程序中记录容器启动时的静态端点

iphone - 使用 addOperationWithBlock 将 block 添加到队列并使用完成 block