objectarx如何在其他线程执行acedprompt_SpringBoot如何使用多线程执行任务

本文介绍了在SpringBoot中利用@EnableAsync和@Async实现异步任务的执行,详细讲解了如何配置自定义线程池,并强调在多线程返回值时需使用Future。同时讨论了在处理Future时可能出现的ExecutionException和InterruptedException两种异常情况。
摘要由CSDN通过智能技术生成

1,SpringBoot中可以使用@EnableAsync和@Async配合来开启异步

package com.cy;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsync //表示开启异步public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

2,在业务层需要异步执行的方法上添加@Async(线程池中配置好的线程方法)

如果使用默认线程池则不需要写括号里面的

33ec6d256bde80814b64857a760c1af4.png

3,自定义线程池配置

@Configurationpublic class SpringThreadPoolConfig {  @Value("${async-thread-pool.corePoolSize}")  private int corePoolSize=2;  @Value("${async-thread-pool.maxPoolSize}")  private int maxPoolSize=5;  @Value("${async-thread-pool.keepAliveSeconds}")  private int keepAliveSeconds=60*5;  @Value("${async-thread-pool.queueCapacity}")  private int queueCapacity=5;    /**创建线程工厂对象:目的是创建线程时为线程起个名字*/  private ThreadFactory threadFactory=new ThreadFactory() {    private AtomicLong count=new AtomicLong(1);//CAS算法    @Override    public Thread newThread(Runnable r) {      return new Thread(r,"db-service-thread-name-"+count.getAndIncrement());    }  };    @Bean  public Executor asyncExecutor() {    System.out.println("corePoolSize="+corePoolSize);    //构建阻塞式队列    BlockingQueue workQueue=    new LinkedBlockingDeque<>(queueCapacity);    //构建线程池对象(tomcat中默认用的线程池也是这个类型)    ThreadPoolExecutor executor=        new ThreadPoolExecutor(corePoolSize,            maxPoolSize,             keepAliveSeconds,             TimeUnit.SECONDS,            workQueue,            threadFactory,            new ThreadPoolExecutor.CallerRunsPolicy());    return executor;  }}

Yml文件中的线程配置

#spring async poolasync-thread-pool:  corePoolSize: 5  maxPoolSize: 10  keepAliveSeconds: 30  queueCapacity: 30

注意,当放多线程执行的方法需要返回值时,需要添加Futrue

(如下示例为一个查询业务,则返回值类型为Futrue的泛型)

@Transactional(propagation = Propagation.REQUIRES_NEW)            @Async("asyncExecutor")            @Override            public Future> findPageObjects(                            String name, Integer pageCurrent) {                    //1.验证参数合法性                    //1.1验证pageCurrent的合法性,                    //不合法抛出IllegalArgumentException异常                    if(pageCurrent==null||pageCurrent<1)                    throw new IllegalArgumentException("当前页码不正确");                    //2.基于条件查询总记录数                    //2.1) 执行查询                                        int rowCount=sysLogDao.getRowCount(name);                    //2.2)验证查询结果,假如结果为0不再执行如下操作                    if(rowCount==0)                    throw new ServiceException("系统没有查到对应记录");                    //3.基于条件查询当前页记录(pageSize定义为2)                    //3.1)定义pageSize                    int pageSize=2;                    //3.2)计算startIndex                    int startIndex=(pageCurrent-1)*pageSize;                    //3.3)执行当前数据的查询操作                    List records=                    sysLogDao.findPageObjects(name, startIndex, pageSize);                    //4.对分页信息以及当前页记录进行封装                    //4.1)构建PageObject对象                    PageObject pageObject=new PageObject<>();                    //4.2)封装数据                    pageObject.setPageCurrent(pageCurrent);                    pageObject.setPageSize(pageSize);                    pageObject.setRowCount(rowCount);                    pageObject.setRecords(records);             pageObject.setPageCount((rowCount-1)/pageSize+1);                    //5.返回封装结果。                    return new AsyncResult>(pageObject);            }

此时返回值Controller时不可以直接获取到数据的,需要从Futre中取出来

e0eaf946652fe3a8c67f00f2e5e2f65f.png

取出时注意处理两个异常

异常1:ExecutionException封装了正在执行的线程抛出的任何异常,所以如果你的线程是做某种IO导致抛出IOException异常的,那么它会被包装在一个ExecutionException中并被重新抛出。

异常2:InterruptedException不是任何出错的迹象。在那里给你一种让你的线程知道什么时候停止的方法,以便他们完成当前的工作并优雅地退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值