![](/img/trans.png)
[英]How to run the same @Scheduled method in Spring Boot in multiple threads
[英]How to run multiple threads of the same process in Java - Spring Boot
我有一個計划任務,它需要在執行時啟動同一進程的多個線程,是否可以設置在進程啟動時啟動的特定線程數?
在應用程序類中,我配置了以下TaskExecutor
bean
@Bean("threadFooExecutor")
public TaskExecutor getFooExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(1000);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("Foo-");
return executor;
}```
@Bean("threadBarExecutor")
public TaskExecutor getBarExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(1000);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("Bar-");
return executor;
}
進程類中配置的異步進程
@Async("threadFooExecutor")
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void print() {
System.out.println(Thread.currentThread().getName() + " " + 1);
System.out.println(Thread.currentThread().getName() + " " + 2);
System.out.println(Thread.currentThread().getName() + " " + 3);
System.out.println(Thread.currentThread().getName() + " " + 4);
}
@Async("threadBarExecutor")
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void print2() {
System.out.println(Thread.currentThread().getName() + " " + 1);
System.out.println(Thread.currentThread().getName() + " " + 2);
System.out.println(Thread.currentThread().getName() + " " + 3);
System.out.println(Thread.currentThread().getName() + " " + 4);
}
我想看到的是這些線程中的每一個同時運行 2 或 3 個,但我只看到每個線程每 3 秒運行一次
我認為你混合了一些東西: TaskExecutor/Executor
配置和調度程序執行的任務的頻率。
此配置意味着任務將每 3 秒執行一次:
@Scheduled(fixedRate = 3000, ...)
添加: @Async("threadBarExecutor")
僅意味着調度程序將使用特定的Executor
來運行任務。
這並不意味着它會在配置的Executor
的線程池大小未滿時Executor
。
所以是的,這兩個任務每 3 秒觸發一次看起來很正常。
如果您想每 3 秒並行運行特定次數的這些任務,@ @Scheduled
是不夠的。
您應該使調度程序方法調用另一個@Asynch
方法。 這可以在同一個 bean 或另一個 bean 中定義,這無關緊要。
@Async("threadFooExecutor")
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void printRepeat3Times() {
for (int i=0; i<3; i++){
print();
}
}
@Async("threadFooExecutor")
public void print() {
// ...
}
請注意,由於這些方法是用@Asynch
注釋的, @Asynch
print()
調用不會“阻塞”當前線程,因此由於ExecutorService
下的ExecutorService
,這些方法可以並行ExecutorService
。
更新:好的,根據您的評論,您需要以下內容:
public class ServiceOne {
@Async
public void bgTask() {
System.out.println(Thread.currentThread().getName());
}
}
public class ServiceTwo {
@Autowired
ServiceOne serviceOne;
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void scheduledRunner() {
int i = 3;
while (i-- >0 ) {
serviceOne.bgTask();
}
}
}
這樣,計划方法將每三秒執行一次,並且會產生三個並行的后台任務。 注入東西是為了讓 AOP 與默認編織器一起工作,如果方法在同一個類中,它將忽略其中一個注釋。
根據文檔,這可能是正在發生的事情:
默認情況下,將搜索關聯的調度程序定義:上下文中唯一的 TaskScheduler bean,或者否則名為“taskScheduler”的 TaskScheduler bean; 還將對 ScheduledExecutorService bean 執行相同的查找。 如果兩者都無法解析,則會在注冊器中創建和使用本地單線程默認調度程序。
我認為配置ScheduledTaskRegistrar
可能會有所幫助:
public class SchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(4); // Number of simultaneously running @Scheduled functions
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.