赞
踩
springboot2.0版本 执行多线程方式,个人学习了两种,一种直接是继承父类Thread或实现Runnable 接口类,,重写run方法;第二种是通过springboot的支持注解@Async的方式。
第一种:自定义类继承Thread类或继承Runnnable接口,重写run方法
- import com.xxx.xx.taskphone.model.PhoneCallin;
- import com.xxx.xxx.taskphone.service.PhoneCallinService;
-
- public class PhoneCallInThread implements Runnable{
-
- private PhoneCallinService phoneCallinService;
- public PhoneCallInThread(PhoneCallinService phoneCallinService) {
- super();
- this.phoneCallinService = phoneCallinService;
- }
- @Override
- public void run() {
- System.out.println("-------------------");
- //phoneCallinService.test();自定义逻辑业务
- }
-
-
- }

开启线程
- @Component
- public class TaskScheduling {
-
- @Autowired
- private PhoneCallinService phoneCallinService;
-
- @Scheduled(fixedRate = 2000)
- public void savePhoneCallin(){
- long size = 5;
- if(size>0){
- new Thread(new PhoneCallInThread(phoneCallinService)).start();
- }
- }
-
- }
注:因为线程处理是执行逻辑的,所以spring无法通过注解的形式来说完成代理的类对象(如此处的phoneCallInService);但是可以通过获取ApplicationSpringContext上下文来获取代理对象。
我这里用的定时任务@scheduled(fixedRate = 2000) 每隔2秒钟执行一次。
第二种:springboot2.0使用@Async进行异步调用
多线程的配置类
- package com.xxx.perform.config;
-
- import java.util.concurrent.Executor;
- import java.util.concurrent.ThreadPoolExecutor;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-
- @Configuration
- public class TaskPoolConfig {
- @Bean("taskExecutor")
- public Executor taskExecutor() {
- ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
- executor.setCorePoolSize(10);//核心线程数目
- executor.setMaxPoolSize(20);//指定最大线程数
- executor.setQueueCapacity(200);//队列中最大的数目
- executor.setKeepAliveSeconds(60);//线程空闲后的最大存活时间
- executor.setThreadNamePrefix("taskExecutor-");//线程名称前缀
- executor.setWaitForTasksToCompleteOnShutdown(true);//设置 线程池关闭 的时候 等待 所有任务都完成后,再继续 销毁 其他的 Bean,确保 异步任务 的 销毁 就会先于 数据库连接池对象 的销毁。
- executor.setAwaitTerminationSeconds(60);//设置线程池中 任务的等待时间
- executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
- executor.initialize();
- return executor;
- }
- }

启动类上开启线程支持
- @EnableAsync
- public class PerformAdminApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(AdminApplication.class, args);
- }
- }
使用@Async注解表明当前类或当前方是一个线程类,并支持多线程处理
- @Scheduled(fixedRate = 2000)
- @Async
- public void test(){
- System.out.println("---------");
- }
需要注意的事,如果多次调用被@Async注解的方法,会每次都会生成一个线程来处理方法逻辑。这样就需要及时处理逻辑后的结果。需要提供方法的返回处理逻辑。
多线程的异步回调
在被注明是线程处理的方法提供回调信息类
- @Async
- public Future<String> doTaskCallback() throws Exception {
- super.doTaskTwo();
- return new AsyncResult<>("任务二完成");
- }
然后直接正常获取返回值就可以了
List<String> result = new Test().doTaskCallback();
最后个人建议在执行下一次的调用之前先判断当前线程是否已经完成,result.isDone()。如果线程未结束,可以Thead.sleep(1000),休眠一定时间后重新执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。