簡體   English   中英

如何在 Java 中運行同一進程的多個線程 - Spring Boot

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM