如何等待弹簧调度程序生成的线程完成?

时间:2019-01-22 04:56:28

标签: java multithreading spring-scheduled

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

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

到目前为止我的想法:在调度程序中,调用UpdatePriceJobs execute方法。此方法首先将列表分成多个块。然后,每个块由ChunkProcessor通过其处理方法进行处理。用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不支持此数据库。

1 个答案:

答案 0 :(得分:0)

尝试使用Java中的Fork/Join框架。Fork/Join是一个并行处理框架。首先,您可以设置并行级别,而无需弄清楚您需要多少个线程。方法awaitTermination可以阻塞当前线程,直到进程完成为止,因此您无需使用CountDownLatch。如果您决定使用Fork/Join,此article可以为您提供帮助。

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