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

如何用线程池并行化单个quartz作业?

宋宇
2023-03-14

我在Spring boot应用程序中有一个quartz调度作业,通过每5分钟激发一次的方法,将一个大列表中的项目发送到一些webservices。

我在下面的代码中尝试了一个ThreadPoolTaskExecutor,其池大小为5个线程。然而,当我执行并检查作业日志时,它说作业只需几秒钟就完成了,但发送所有数据需要几分钟。它继续正常工作,但工作似乎在几秒钟内完成。它可能表示在设置了所有线程之后作业就完成了。这是我避免的,因为我不知道作业执行时间和日志。

@Autowired
MyService myService;

@NonTransactionalService 
public class MySenderService{

    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setCorePoolSize(5);
    taskExecutor.setMaxPoolSize(5);
    taskExecutor.initialize();

    public void sendAll(){
        List<Long> largeList = someMethod();
        largeList.stream().forEach(i -> {
            taskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    myService.send(i);
                }
            });
        }
    }
}

那么,如何在一个作业中使用多个工作者来运行这个发送方法呢?
或者设置多个相同的作业来通过相同的方法发送相同的列表是一个好的做法吗?

共有1个答案

谭泉
2023-03-14

您可以尝试使用Flux,IMHO是需要更少代码的解决方案:

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(5);
        taskExecutor.initialize();

        List<Integer> largeList = someMethod();
        System.out.println(largeList);
        Flux.fromStream(largeList.stream())
                .parallel(5)
                .runOn(Schedulers.fromExecutor(taskExecutor))
                .subscribe( x -> { System.out.println(x);});

        taskExecutor.shutdown();

不要忘记关闭TaskExecutor,但要作为@M。Deinum说,最好是让它在别处创建并注入到你的服务中。

 类似资料:
  • 我需要创建一个并行执行多个操作的应用程序。我曾考虑过使用线程或线程池,但我以前从未使用过,所以我发现这相当困难。Thread应按以下方式工作: 所有系统应同时运行。你认为我应该如何实现这一点?

  • 我正在使用启动作业。问题:我如何线程化这些调用?以便最多有4个作业线程可以并发运行,而任何其他作业都只是排队?

  • 我注意到一些web框架(如Play Framework)允许您配置多个不同大小的线程池(线程池中的线程数)。假设我们在单核的单机中运行这个游戏。拥有多个线程池不会有很大的开销吗?

  • 我想同时向一个webservice发送webservice调用。最多应有20个并行请求等待webservice响应。任何其他请求都应该等待它们完成。 如果一个用户向我发送一个请求,这通常会导致向目标服务器发送5个并行请求。因此,我一次最多可以服务20/5=4个用户。其他人将不得不等待,这很好。或者被高负荷拒绝。 问题:我应该使用哪个线程池,以及如何配置它? 我读了上面的内容如下:主池可以向网络服务

  • 问题内容: 我们有一个基于石英的调度程序应用程序,该应用程序每分钟运行约1000个作业,每分钟的秒数均匀分布,即每秒约16-17个作业。理想情况下,这16-17个作业应同时触发,但是该作业的execute方法的第一个语句(仅记录执行时间)非常晚。例如,假设我们从05:00到05:04每分钟安排1000个作业。因此,理想情况下,计划在05:03:50进行的作业应该在05:03:50记录了execut

  • 问题内容: 在Java中拥有多个线程池的优缺点是什么?我已经看过代码,其中有多个线程池用于不同的“类型”任务,而且我不确定它是更好的设计还是只是开发人员感到懒惰。一个示例是将ScheduledThreadPoolExecutor用于定期执行的任务或具有超时的任务,而将另一ThreadPoolExecutor用于其他任务。 问题答案: 具有单独的专用线程池的目的是,使活动不会因线程不足而被饥饿,因为