SpringBoot 异步任务

Springboot异步任务

1、在编写之前,我们需要在Pom文件种添加 starter-web依赖组件,只有加入这个之后,才可以加入异步服务。

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2、需要在Springboot入口类也就是应用启动类加入 一个允许异类的注解,去表示当前应用需要使用异步任务

 

*@EnableScheduling //允许当前应用开启定时任务
* @EnableAsync //开启异步支持
* */
@EnableAsync //开启异步支持
@SpringBootApplication //表示当前是springboot应用
@EnableScheduling //允许当前应用开启定时任务
public class springapplicationstudy {

  

 

 3、编写异步服务类

在处理异步服务的是时候,异步服务类需要被SpringBoot 扫描到,需要在异步类添加一个bean注解。@Service 或者Component 

两者都是SpringBoot Bean  只不过@Component是基础类。

默认异步任务线程池配置,是不能重新利用线程池的,一个异步任务会起一个任务,这样会造成很大的一个资源浪费。

默认线程池的配置比较简单,一般情况需要定制优化一个线程池。

@Slf4j
@Service
public class AsyncService {
    @Async
    public void AsyncProcess() throws InterruptedException{
         log.info("Async process Task Current thread name ---> {}",
                 Thread.currentThread().getName());//获取当前线程池的名称
        TimeUnit.SECONDS.sleep(2); //Jave 并发的一个插件。

    }

    //有返回值
    @Async
    public Future <Integer> AsyncProcessHasReturn() throws InterruptedException {
       log.info("Async Process [Has Return ],Get current thread name  ----> {}",
               Thread.currentThread().getName());
       TimeUnit.SECONDS.sleep(2);
        return new AsyncResult<>(100);
    }

}

  

 4、编写线程池配置类

编写自定义异步线程池,既然是配置那么配置注解肯定少不了了。

之程序的开始添加 @Configuration

首先申明一个线程池的对象,然后对线程池进行优化配置。

 

实现 AsyncConfigurer 重写 两个方法

getAsyncExecutor 线程池配置

 

  • setCorePoolSize //线程池核心数量
  • setMaxPoolSize //最大线程池数量,超过核心的进程以外的进程
  • setQueueCapacity //缓冲队列的个数
  • setKeepAliveSeconds // 超出的核心进程数量以外的进程存活时间
  • setThreadNamePrefix // 线程池前缀
  • setWaitForTasksToCompleteOnShutdown //是否等待所有线程执行完毕之后关闭线程池 默认false
  • setAwaitTerminationSeconds //等待时间

 

//拒绝策略

  • AbortPolicy() //当线程池满了,队列也满了,它会直接废弃并且报出异常
  • CallerRunsPolicy() //如果执行程序已经关闭了,则会丢弃这个任务
  • DiscardOldestPolicy() //当线程数量等于最大线程数量,队列是满的情况下,它就会抛弃线程池种最后一个,并执行新传递进来的任务
  • DiscardPolicy()  //当线程数量等于或最大线程数量,不做任何的操作      
//线程池初始化

initialize

 

 


getAsyncUncaughtExceptionHandler 进程异常处理

实现并且重写

AsyncUncaughtExceptionHandler 中的 handleUncaughtException 方法

 

package com.caicai.springboot.study.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;

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

import java.lang.reflect.Method;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;


/*
*
* 自定义异步线程池的配置
*
* */
@Slf4j
@Configuration //配置类注解
public class AsyncConfig  implements AsyncConfigurer {

    //这里的Executor 是ThreadPool 它会返回一个线程池
    //需要把这个注入到JavaBean
    @Bean
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);//线程池核心数量
        executor.setMaxPoolSize(20);//最大的线程池数量,也就超过核心池的时候,才会使用的
        executor.setQueueCapacity(30);//缓冲队列的个数
        executor.setKeepAliveSeconds(60);// 超出核心进程数量之外的线程数量的最大存活时间。默认60秒,超过则会被杀掉
        executor.setThreadNamePrefix("Caicai_Async_");//线程名的前缀

        executor.setWaitForTasksToCompleteOnShutdown(true);//是否等待所有线程执行完毕之后关闭线程池
        executor.setAwaitTerminationSeconds(60); // 等待的时间,默认是0.也就是setWaitForTasksToCompleteOnShutdown 这个的等待时间

        //拒绝策略
        //用与被拒绝处理的一个处理程序,它直接在executor 的方法的调用线程中运行被拒绝的任务
        executor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.AbortPolicy()
                //AbortPolicy() 当线程池满了,队列也满了,它会直接废弃并且报出异常
                //CallerRunsPolicy() //如果执行程序已经关闭了,则会丢弃这个任务
                //DiscardOldestPolicy() 当线程数量等于最大线程数量,队列是满的情况下,它就会抛弃线程池种最后一个,并执行新传递进来的任务
                //DiscardPolicy()  当线程数量等于或最大线程数量,不做任何的操作
        );

        //线程初始化
        executor.initialize();


        return executor;
    }
    // getAsyncUncaughtExceptionHandler 定义异常处理
    /*
    * 定义异步任务异常处理类,只会处理没有返回结果异步任务,有返回结果的任务会
    * 交给客户端
    *
    * */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }

    static class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler{


        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
             log.info("AsyncError:{} ,Method:{},Param:{}",throwable.getMessage(),method.getName(),
                     JSON.toJSONString(objects));//返回值,以json的形式返回
             throwable.printStackTrace();//打印
             //TODO 发送邮件或者手机短信

        }



    }
}

  

5、在异步服务类的异步注解添加指定线程池名称

@Async("getAsyncExecutor")//指定使用线程池名称

   

 

posted @ 2021-01-31 14:50  菜菜920  阅读(332)  评论(0编辑  收藏  举报