我有一个场景,大约将数百万数据插入到后端,目前使用executor框架来加载。我将用更简单的术语来解释我的问题。
在下面的例子中,我有10个runnable和3个线程来执行相同的代码。考虑到我的runnable正在执行插入操作,并且它需要时间来完成任务。当我检查时,可以理解的是,如果所有线程都很忙,其他任务将进入队列,一旦线程完成任务,它将从池中获取任务并完成任务。
因此,在本例中,将创建SampleRunnable 4到10的对象,该对象将位于池中。
问题:由于我需要加载数百万个任务,我无法加载队列中的所有记录,这可能会导致内存问题。所以我的问题是,是否可以让主线程等待,直到任何一个executor工作线程可用,而不是处理队列中的所有任务。
以下是我尝试过的方法,而不是让这么多任务排队:
方法1:对executor使用数组阻塞队列,并给出大小为5(例如)因此,在本例中,当第9个任务到来时,将抛出RejectedExecutionException,并在catch子句中,休眠1分钟,当线程可用时,递归尝试same.This将在任何一次重试中被拾取。
方法2:使用关闭并等待终止。也就是说,如果任务计数为5,我将关闭并等待终止。在等待终止'if‘块(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();
}发布于 2019-10-19 02:46:11
听起来问题是,您想要限制主线程,这样它就不会超前于工作线程。如果是这样,那么可以考虑显式地构造一个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));
}
...https://stackoverflow.com/questions/58453620
复制相似问题