运行 计划方法内的 ExecutorService
Running ExecutorService inside scheduled method
我有一个关于执行器线程池的问题,运行ninng 一个在另一个里面。
假设我有 Spring 具有预定方法的服务,其他服务创建了 ExecutorService 和 运行s 一些操作方法
@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 机器上执行相同的作业并且执行时间相同。
谢谢。
它如何分布在 CPU 个核心上也取决于操作系统的繁忙程度,但假设没有其他情况发生,每个 CPU 个核心能够执行一个线程。如果活动线程多于 CPU 个内核,则操作系统负责在线程之间分配 CPU 时间。
在您的示例中,一个线程将执行@Scheduled 方法,该方法非常快,因为它不做太多事情,只需向执行程序服务提交一个新操作即可。
然后最多有 20 个线程的执行器服务将在 20 个线程中的第一个可用线程上执行操作。
所以答案是肯定的,操作将并行进行。
您可以尝试经常安排您的方法,比如说每秒:
@Scheduled(cron = "* * * ? * *")
然后在你的动作中做一些超过 1 秒的动作(否则动作将在下一个时间表之前完成)。您将看到并行执行该工作的操作。
顺便问一下,为什么不使用 ScheduledExecutorService 呢?或者配置 spring 使用多个线程?
我有一个关于执行器线程池的问题,运行ninng 一个在另一个里面。
假设我有 Spring 具有预定方法的服务,其他服务创建了 ExecutorService 和 运行s 一些操作方法
@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 机器上执行相同的作业并且执行时间相同。
谢谢。
它如何分布在 CPU 个核心上也取决于操作系统的繁忙程度,但假设没有其他情况发生,每个 CPU 个核心能够执行一个线程。如果活动线程多于 CPU 个内核,则操作系统负责在线程之间分配 CPU 时间。
在您的示例中,一个线程将执行@Scheduled 方法,该方法非常快,因为它不做太多事情,只需向执行程序服务提交一个新操作即可。
然后最多有 20 个线程的执行器服务将在 20 个线程中的第一个可用线程上执行操作。
所以答案是肯定的,操作将并行进行。
您可以尝试经常安排您的方法,比如说每秒:
@Scheduled(cron = "* * * ? * *")
然后在你的动作中做一些超过 1 秒的动作(否则动作将在下一个时间表之前完成)。您将看到并行执行该工作的操作。
顺便问一下,为什么不使用 ScheduledExecutorService 呢?或者配置 spring 使用多个线程?