java - 如果 ExecutorService 的队列已满会发生什么

标签 java concurrency runtime-error out-of-memory

我有一个高达 TB 的大文件,我的任务是逐行处理。每行需要 5 秒才能完成。为了提高性能,我将进程分派(dispatch)到这样的固定线程池

ExecutorService executor = Executors.newFixedThreadPool(5);     

while ((line = br.readLine()) != null) {
  Runnable worker = new WorkerThread(line);
  executor.execute(worker); 
}

我的问题是,如果我放置如此多的任务使执行程序的队列不堪重负,会发生什么情况。它会抛出 StackOverflow 吗?

最佳答案

这可能有点偏离主题,但解决此问题的一个选项是使用固定长度的阻塞队列并使用 ThreadPoolExecutor.CallerRunPolicy()。这样,如果消费者不够快(因此队列被填满),那么调用者线程(生产者)将被用来运行任务本身。我们可以像下面这样初始化一个执行器:

executorService = new ThreadPoolExecutor(DEFAULT_THREAD_COUNT,
        DEFAULT_THREAD_COUNT, 2, TimeUnit.MINUTES,
        new ArrayBlockingQueue<Runnable>(DEFAULT_QUEUE_LENGTH),
        new ThreadPoolExecutor.CallerRunsPolicy());

From the API: “拒绝任务的处理程序直接在执行方法的调用线程中运行被拒绝的任务,除非执行程序已关闭,在这种情况下任务将被丢弃。”

关于java - 如果 ExecutorService 的队列已满会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20509947/

相关文章:

java - 在 Java Swing 中使用 MigLayout

java - 为什么继承深度在 GAE 上的 Datanucleus JDO 中很重要?

python - Matplotlib 错误发生在我第一次运行 Jupyter 单元格但不是第二次

c - 出现错误 : Stack around the variable was corrupted

java - 从 Java 到 Kotlin

java - Hibernate:在 Servlet 中运行时找不到合适的驱动程序

java - 如何有效地重置线程池

java - 如何让 java.concurrency.CyclicBarrier 按预期工作

java - 替代 CopyOnWriteArrayList 用于频繁写入,偶尔迭代

c++ - 插入排序中的运行时错误