【问题标题】:How to wait for threads spawned from a spring-scheduler to complete?如何等待从 spring-scheduler 产生的线程完成?
【发布时间】:2019-01-22 04:56:27
【问题描述】:

我正在使用 spring-scheduler 并从 @Scheduled 方法产生多个线程(其中一个有一个休息调用)。 @Scheduled 方法中等待所有线程完成然后退出的最佳方式是什么?

应用程序详细信息: 我有一个计划任务,其中我从数据库中获取一个列表单一类型的对象(比如类订单),将它们分成块(所以如果我得到 5000 个订单,我会分成 5 块,每块 1000 块)。然后我遍历每个块,对于块中的每个订单,我从Order 获取产品列表,然后遍历它们。对于每个产品,我需要对另一个服务进行休息调用,该服务返回我需要在该产品中设置的值(例如价格)。这计划每 1 小时执行一次(可配置)。

到目前为止我的想法: 在调度程序中,调用UpdatePriceJobs 执行方法。此方法首先将列表分成块。然后每个块由ChunkProcessor 通过其处理方法处理。 process 方法使用 spring @Async 注解,以便每个块在单独的线程中处理。然后它调用 productProcessor 服务上的 process 方法,该方法进行其余调用。此方法再次使用@Async 进行注释。所以想法是并行运行Chunks,然后进行并行价格更新调用。如您所见,我将不得不等待所有线程完成,否则某些产品将无法获得更新的价格。

我首先想到的是倒计时锁。但是,我将不得不传递它以递减计数器,然后必须计算将创建的线程数。

@Override
public void process(Chunk<Order> chunk) {
    final List<Chunk<Order>> chunks = orderChunkProvider.getChunks(items);
    for (final Chunk<Order> chunk : chunks) {
        OrderChunkProcessor.process(chunk);
    }

}

@Async
@Override
public void process(Chunk<Order> chunk) {
    final List<Order> orders = chunk.getItems();
    for (final Order order : orders ) {
        final List<Product> products = order.getProductss();
        for (final Product product : products ) {
            productProcessor.process(product);
        }
 }

productProcessor.process(product) 方法进行其余调用,并且还使用 @Async 进行注释

等待所有线程创建的最佳方式是什么?还是设计完全有缺陷,需要进行一些重大更改。

PS:我不能使用 spring-batch,因为我们使用的是不支持事务的 NoSql 数据库,而 spring-batch 不支持这个。

【问题讨论】:

    标签: java multithreading spring-scheduled


    【解决方案1】:

    试试java中的Fork/Join框架。Fork/Join是一个并行处理框架。第一,你只能设置并行级别,不需要弄清楚你需要多少线程。第二,还有方法awaitTermination可以阻塞当前线程直到进程完成,所以你不需要使用CountDownLatch。如果您决定使用Fork/Join,这个article 可以帮助您。

    注意,@Async只使用线程池执行任务,如果任务需要更多时间可能会影响其他任务。

    【讨论】:

    • ForkJoinPool 似乎有很多问题:coopsoft.com/ar/CalamityArticle.html
    • 如果你不使用其他专业库,我认为使用 Fork/join 是一个不错的选择,你可以尝试管理这个任务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 2010-12-07
    • 1970-01-01
    • 2010-11-18
    • 2015-08-29
    相关资源
    最近更新 更多