SpringBoot之@EnableAsync、@Async使用

@EnableAsync、@Async注解使用

启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 使用@Async注解需要在启动类加@EnableAsync注解
 */
@SpringBootApplication
@EnableAsync
public class AsyncApplication {

    public static void main(String[] args) {
        SpringApplication.run(AsyncApplication.class, args);
    }

}

@Async使用:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class TaskService {

    /**
     * @Async("taskExecutor")表示使用自定义线程池
     */
    @Async("taskExecutor")
    public void sendMessage1() {
        System.out.println(Thread.currentThread().getName() + "发送短信开始1 ...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "发送短信结束1 ...");
    }

    @Async("taskExecutor")
    public void sendMessage2() {
        System.out.println(Thread.currentThread().getName() + "发送短信开始2 ...");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "发送短信结束2 ...");
    }


    private int batchInsert() {
        List<Integer> numList = new ArrayList<>(100000);
        for (int i = 0; i < 100000; i++) {
            numList.add(i);
        }
        return 1;
    }

    /**
     * @Async使用SpringBoot默认线程池
     */
    @Async
    public void batchAdd() {
        System.out.println(Thread.currentThread().getName() + "批量添加数据开始 ...");
        batchInsert();
        System.out.println(Thread.currentThread().getName() + "批量添加数据结束 ...");
    }

}

controller层:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import xinhaima.com.async.service.TaskService;

@RestController
public class TaskController {

    @Autowired
    private TaskService taskService;

    @RequestMapping(value = "/send", method = RequestMethod.GET)
    public void sendMsg() {
        taskService.batchAdd();
        taskService.sendMessage1();
        taskService.sendMessage2();
    }

}

线程池配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 */
@Configuration
public class ThreadPoolTaskConfig {

    /**
     * 核心线程数(默认线程数)
     */
    private static final int corePoolSize = 20;
    /**
     * 最大线程数
     */
    private static final int maxPoolSize = 100;
    /**
     * 允许线程空闲时间(单位:默认为秒)
     */
    private static final int keepAliveTime = 10;
    /**
     * 缓冲队列大小
     */
    private static final int queueCapacity = 200;
    /**
     * 线程池名前缀
     */
    private static final String threadNamePrefix = "Async-Service-";

    @Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveTime);
        executor.setThreadNamePrefix(threadNamePrefix);

        // 线程池对拒绝任务的处理策略
        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }

}

如下方式会使@Async失效:

  • 异步方法使用static修饰
  • 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
  • 异步方法不能与被调用的异步方法在同一个类中
  • 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
  • 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解

转载文章:https://www.toutiao.com/i6807650160445751820/

原文地址:https://www.cnblogs.com/mxh-java/p/14401833.html