springboot2.0 多线程并发执行任务
作者:互联网
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),休眠一定时间后重新执行。
我是小佣兵 发布了21 篇原创文章 · 获赞 2 · 访问量 1万+ 私信 关注标签:springboot2.0,new,phoneCallinService,并发,线程,executor,import,多线程,public 来源: https://blog.csdn.net/lansonan1005/article/details/103969186