java - Spring-boot @Async 未与 @Scheduled 一起运行

标签 java spring spring-boot spring-scheduled spring-async

我用过this tutorialit's github project作为本次 SSCCE 的基础。

出于未知原因,标记为 @Async 的方法从 @Scheduled 方法运行,始终同步执行。

我正在寻找修复或解决方法,以使 performTask() 中的代码异步运行。

以下类(class):

应用程序.java

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application implements AsyncConfigurer{

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }

    @Override
    @Bean(name="asyncExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
        exec.setMaxPoolSize(Runtime.getRuntime().availableProcessors()*2);
        exec.setThreadGroupName("MyCustomExecutor");
        exec.setWaitForTasksToCompleteOnShutdown(true);
        exec.setBeanName("asyncExecutor");
        exec.initialize();
        return exec;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

MyAsyncService.java

@Service
public class MyAsyncService {

    static AtomicInteger taskNoCounter = new AtomicInteger();

    public MyAsyncService() {
    }

    @Async("asyncExecutor")
    public void performTask() {
        int delayMs = (int) (System.currentTimeMillis()%1000+1000);
        int taskNo = taskNoCounter.incrementAndGet();
        String taskInfo = "MyAsyncTask [taskNo=" + taskNo + ", delayMs=" + delayMs + ", threadId="+Thread.currentThread().getId()+"]";
        System.out.println("+ start " +taskInfo);
        try {
            Thread.sleep(delayMs);
        } catch (InterruptedException e) {
            // empty on purpose
        }
        System.out.println("- end   " +taskInfo);
    }

}

计划任务.java

@Component
public class ScheduledTasks {

    @Autowired
    MyAsyncService service;

    @Scheduled(fixedRate = 1000)
    public void reportCurrentTime() {
        for (int i=0; i<20; i++) {
            service.performTask();
        }

    }
}

产生以下同步结果:

+ start MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
- end   MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
+ start MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
- end   MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
+ start MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
- end   MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
+ start MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
- end   MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
+ start MyAsyncTask [taskNo=5, delayMs=1994, threadId=16]

最佳答案

问题在于未设置 ThreadPoolTask​​ExecutorcorePoolSize 属性。

默认情况下,corePoolSize1,只有当队列已满时,线程数量才会增加。由于我的队列是无限的,因此池中没有创建任何其他线程。

我最终做了:

exec.setCorePoolSize(Runtime.getRuntime().availableProcessors()+1);

关于java - Spring-boot @Async 未与 @Scheduled 一起运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35195982/

相关文章:

java - 如何在java中检查密码是否是BCrypt编码的

docker 中 rabbitmq 的 Spring Boot 应用程序问题

java - 未找到具有 URI 的 HTTP 请求的映射(spring 4.1 注释配置)

spring-boot - 带有 Spring Boot 应用程序的 logack 中的 is_undefined 目录错误

PDF 中的 Java 数据

java - 用于 SWT/AWT 的图形可视化库

java - 如何在没有 Spring Boot 的情况下使用 JPA 存储库

java - ShardedJedis 和 JedisCluster 有什么区别

java - 使用我的网站一段时间后,我需要重新启动 glassfish

java - 如何在 MockRestServiceServer 中验证 json 请求正文