springboot创建线程池,异步执行业务代码

首先创建一个配置类

@Configuration和@EnableAsync这两个注解,表示这是个配置类,并且是线程池的配置类


	@Configuration
	@EnableAsync
	public class ExecutorConfig {
	
	    private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
	
	    @Bean
	    public Executor asyncServiceExecutor() {
	        logger.info("start asyncServiceExecutor");
	        //ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
	
	        //使用继承类,查看线程状态
	        ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
	                //配置核心线程数
	        executor.setCorePoolSize(5);
	        //配置最大线程数
	        executor.setMaxPoolSize(5);
	        //配置队列大小
	        executor.setQueueCapacity(99999);
	        //配置线程池中的线程的名称前缀
	        executor.setThreadNamePrefix("async-service-");
	
	        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
	        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
	        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
	        //执行初始化
	        executor.initialize();
	
	        return executor;
	
	    }
	}

创建一个service类


public interface AsyncService {

    /**
     * 执行异步任务
     */
     void executeAsync();
}

创建service的实现类

asyncServiceExecutor是前面ExecutorConfig.java中的方法名,表明executeAsync方法进入的线程池是asyncServiceExecutor方法创建的

@Service
public class AsyncServiceImpl implements AsyncService {

    private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);

    @Override
    @Async("asyncServiceExecutor")//asyncServiceExecutor是前面ExecutorConfig.java中的方法名,表明executeAsync方法进入的线程池是asyncServiceExecutor方法创建的
    public  void executeAsync() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

        logger.info("异步开始---"+df.format(new Date()));
        try{
            Thread.sleep(2000);
        }catch(Exception e){
            e.printStackTrace();
        }
        SimpleDateFormat dfa = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

        logger.info("异步结束---"+dfa.format(new Date()));
    }
}

创建cntorller

@RestController
public class AsyncController {

    private static final Logger logger = LoggerFactory.getLogger(AsyncController.class);
    @Autowired
    private AsyncService asyncServ1ice;

    @RequestMapping("hello")
    public  String hello(){
        logger.info("请求开始");

        asyncServ1ice.executeAsync();


        logger.info("请求返回");

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        return df.format(new Date());
    }
}

下面我们创建一个类来实现ThreadPoolTaskExecutor,用于查看线程状态

public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
    private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class);

    private void showThreadPoolInfo(String prefix){
        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();

        if(null==threadPoolExecutor){
            return;
        }

        logger.info("{}, {},任务总数:taskCount [{}], 已完成数:completedTaskCount [{}], 活跃线程数:activeCount [{}], 队列大小:queueSize [{}]",
                this.getThreadNamePrefix(),
                prefix,
                threadPoolExecutor.getTaskCount(),
                threadPoolExecutor.getCompletedTaskCount(),
                threadPoolExecutor.getActiveCount(),
                threadPoolExecutor.getQueue().size());
    }

    @Override
    public void execute(Runnable task) {
        showThreadPoolInfo("1. do execute");
        super.execute(task);
    }

    @Override
    public void execute(Runnable task, long startTimeout) {
        showThreadPoolInfo("2. do execute");
        super.execute(task, startTimeout);
    }

    @Override
    public Future<?> submit(Runnable task) {
        showThreadPoolInfo("1. do submit");
        return super.submit(task);
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        showThreadPoolInfo("2. do submit");
        return super.submit(task);
    }

    @Override
    public ListenableFuture<?> submitListenable(Runnable task) {
        showThreadPoolInfo("1. do submitListenable");
        return super.submitListenable(task);
    }

    @Override
    public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
        showThreadPoolInfo("2. do submitListenable");
        return super.submitListenable(task);
    }
}

看看打印出来的东西

2019-10-03 20:04:37.837  INFO 4208 --- [nio-8080-exec-9] c.threadpool.contorller.AsyncController  : 请求开始
2019-10-03 20:04:37.838  INFO 4208 --- [nio-8080-exec-9] c.t.c.VisiableThreadPoolTaskExecutor     : async-service-, 2. do submit,任务总数:taskCount [13], 已完成数:completedTaskCount [13], 活跃线程数:activeCount [0], 队列大小:queueSize [0]
2019-10-03 20:04:37.838  INFO 4208 --- [nio-8080-exec-9] c.threadpool.contorller.AsyncController  : 请求返回
2019-10-03 20:04:37.838  INFO 4208 --- [async-service-4] c.t.service.impl.AsyncServiceImpl        : 异步开始---2019-10-03 20:04:37
2019-10-03 20:04:39.839  INFO 4208 --- [async-service-4] c.t.service.impl.AsyncServiceImpl        : 异步结束---2019-10-03 20:04:39

上面可以看出,contorlle里面调用的service方法是异步执行的,而且线程的状态也在监控中可以查看,这个对于小项目很实用,因为你可能会因为要异步执行去考虑消息队列,这样有点麻烦,用线程异步执行就比较方便,当然用什么技术还是要结合自己的实际业务,技术没有最好的,只有最合适的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值