【问题标题】:Running ExecutorService inside scheduled method在预定方法中运行 ExecutorService
【发布时间】:2020-12-13 11:27:44
【问题描述】:

我有一个关于执行器线程池的问题,一个在另一个内部运行。

假设我有带有预定方法的 Spring 服务,其他服务创建 ExecutorService 并运行一些操作方法

@Service
public class ScheduledService
{

    @Autowired
    WorkService workService;

    @Scheduled(cron = "1 * * * * * ")
    public void method() {
        workService.execute();

    }
}

@Service
public class WorkService {

    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    public void execute() {
        executorService.submit(()->action());
    }

    private void action() {
        //some action
    }
}

据我所知,@Scheduled 的默认池大小为 1。在此池的内部线程中,我正在尝试使用更大的池创建新的 executorService。

所以问题是 - 执行将如何分布在 CPU 内核上,执行器服务真的会并行工作吗?我有一种感觉,它没有。我尝试在 2 个 vCore 和 4 个 vCore 机器上运行相同的作业,并且执行时间相同。

谢谢。

【问题讨论】:

    标签: java spring multithreading executorservice


    【解决方案1】:

    它在 CPU 内核上的分布方式还取决于操作系统的繁忙程度,但我们可以说没有其他事情发生,每个 CPU 内核都能够执行一个线程。如果活动线程多于 CPU 内核,则操作系统负责在线程之间分配 CPU 时间。

    在您的示例中,一个线程将执行@Scheduled 方法,该方法非常快,因为它不会做太多事情,只需向执行器服务提交一个新操作即可。

    然后执行器服务(最多有 20 个线程)将在 20 个线程中的第一个可用线程上执行操作。

    所以答案是肯定的,动作将并行进行。

    您可以尝试经常安排您的方法,比如说每秒:

    @Scheduled(cron = "* * * ? * *")
    

    然后在你的动作中做一些超过 1 秒的动作(否则动作将在下一个时间表之前完成)。您将看到并行执行该工作的操作。

    顺便说一句,为什么不使用 ScheduledExecutorService 呢?或者配置spring使用多个线程?

    【讨论】:

    • 谢谢!是的,我添加了一些日志来打印线程名称,它可以并行工作。关于 ScheduledExecutorService - 在实际代码中逻辑更复杂。新消息的预定服务轮询队列,如果它收到一条消息 - 它开始处理,并且只有在处理的一个部分中我可以并行处理。
    猜你喜欢
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2015-07-06
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多