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

在循环中为批次处理作业重新创建ExecutorService

薛涛
2023-03-14

示例:我需要处理数百万条记录,我想并行处理它们以加快处理速度。为此,我想在Executor服务中使用线程池。每项任务最多需要几秒钟。为了避免在一个线程池中为每条记录创建数百万个线程,这会导致内存问题,我决定分批处理记录。

我想为每个批使用一个新的线程池。我让Executor Service等待批处理任务完成,然后关闭Executor Service并创建一个新的Executor Service来处理下一批。我会这样做:

/*...................*/
int count = 1;
ExecutorService executor = buildExecutor(CORE_THREADS, MAX_THREADS);
            while (/* there is a record */) {
                executor.execute(new ProcessRecordThread(record));
                count++;
                if (count % BATCH_SIZE == 0) {
                    executor.shutdown();
                    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                    executor = buildExecutor(CORE_THREADS, MAX_THREADS);
                }
            }
 /*................*/

创建Executor服务的方法

private static ExecutorService buildExecutor(int corePoolSize, int maximumPoolSize) {
            return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0L,
                    TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue(),
                    Executors.defaultThreadFactory());
        }

我知道创建线程池会给处理增加一些开销。在循环中创建executor服务被认为是不好的做法。我有没有应该注意的权衡?

有没有办法通过使用一个线程池来实现这种行为?

共有1个答案

晏兴发
2023-03-14

Build类有一个静态公共数据源,如单例模式中的C3P0(开源),用于管理连接。

配置c3p0。maxPoolSize=x,运行x个线程从数据源获取连接,然后执行sql。

public class C3P0Pool {
    private static ComboPooledDataSource CPDS = new ComboPooledDataSource("c3p0");
    public static Connection getConnection() throws SQLException {
        return CPDS.getConnection();
    }
    public static DataSource getDataSource() {
        return CPDS;  // QueryRunner could constructed with DataSource
    }
}

您不必关闭数据源,连接将在执行连接时返回到数据源。关闭()。

 类似资料:
  • 我已经将我的Spring批处理配置为每当通过API调用从UI发出请求时触发作业。我面临的问题是,该作业仅在第一次和其他尝试时工作正常,每当调用时,作业不会以预期的方式响应。似乎他们正在尝试恢复,但我想再次重新启动整个执行。感谢您提前提供的任何帮助。 主要的班 配置班 JobListener.class 我的听众。班 Controller.class 应用属性 首次发出API请求时的响应 其他时间的

  • 我正在做简单的Spring批量工作。当我启动作业时,它在无限循环中运行。它不会停止。根据我的时间表,它应该每10秒运行一次。但当工作开始时,它不会停止。它只是分别从读卡器、处理器和写入器打印系统输出。我正在为读者、处理者和作者创造工作机会。我正在按注释进行所有配置。不是通过xml。 下面是批处理配置 PersonReader。JAVA 人Writer.java 个人处理器。JAVA

  • 添加工作到批处理作业 在“常规”选项卡的底部窗格中,选择工作类型,然后如有需要浏览连接、数据库和/或模式以找出你想运行的工作。 你可以双击或拖放工作来将工作从“可用的工作”列表移动到“已选择的工作”列表。若要从已选择的工作列表删除工作,请以相同的方式移除它们。你可以在一个批处理作业中运行来自不同服务器的配置文件。 若要重新排序工作的序列,可使用 “上移”或 “下移”按钮。 如果你想备份整个服务器,

  • 添加工作到批处理作业 在“常规”选项卡的底部窗格中,选择工作类型,然后如有需要浏览连接、数据库和/或模式以找出你想运行的工作。 你可以点击 或 来将已选择的工作或所有工作从“可用的工作”列表移动到“已选择的工作”列表。若要从已选择的工作列表删除已选择工作或所有工作,请点击 或 。你可以在一个批处理作业中运行来自不同服务器的配置文件。 若要重新排序工作的序列,可在已选择的工作列表中拖拉工作到所需的位

  • 添加工作到批处理作业 在“常规”选项卡的底部窗格中,选择工作类型,然后如有需要浏览连接、数据库和/或模式以找出你想运行的工作。 你可以双击或拖放工作来将工作从“可用的工作”列表移动到“已选择的工作”列表。若要从已选择的工作列表删除工作,请以相同的方式移除它们。你可以在一个批处理作业中运行来自不同服务器的配置文件。 若要重新排序工作的序列,可使用 “上移”或 “下移”按钮。 如果你想备份整个服务器,

  • 这似乎是一个愚蠢的问题。我正在尝试为Spring Batch作业存储库(Spring Batch 2.1.7)配置Oracle10g数据库,我能够使用在core中的org/spring框架/批/core/schema-oracle10g.sql可用的脚本创建表。我还将属性batch.data.source.init设置为false。 在干净的数据库上,我的批处理程序运行良好,成功地创建了所有批处理