Springboot:异步任务的多线程管理

在之前ssm的博客中就已经讲过,在日常的项目开发中,我们免不了会遇到高并发或者占用资源比较多的操作,此时使用多线程并发解决这些问题可以提高程序的运行性能;然而仅仅使用线程池管理线程会有一些弊端,虽然线程池能够解决对象资源浪费的问题,但是没有统一维护所有的异步任务。

所以我们在日常编写代码时,要有一个可以统一维护所有异步任务的方法。

线程管理步骤如下:

一.线程池配置

在yml配置文件中配置线程池需要的配置:

spring:   
  task:
    execution:
      pool:
        core-size: 20
        max-size: 100
        queue-capacity: 100

二.维护所有异步任务的工具类AsyncTaskFactory

        该类里面包含所有的异步任务,返回值都为runnable,比如发送验证码、上传文件等比较占资源的任务。

工具类构造必须要私有化,所有异步任务方法为静态方法。

例:

public class AsyncTaskFactory {

    private AsyncTaskFactory() {
    }

    public static Runnable emailCode() {
        return () -> {
            System.out.println("发送邮箱验证码....."+Thread.currentThread().getName());
        };
    }

    public static Runnable phoneCode() {
        return () -> {
            System.out.println("发送手机验证码.....");
        };

    }

    public static Runnable uploadFile() {
        return () -> {
            System.out.println("上传文件到云端....."+Thread.currentThread().getName());
        };
    }
}

三.手动获得容器对象的工具类SpringUtil

并且我们也不想在controller中都加@autowried去添加这些类,所以我们把他们都构造私有化成为工具类,但工具类无法实例化对象,所以在springapplicationcontext容器里找不到这些工具类里实例化的对象;理论上异步线程管理类AsyncTaskManager和ssm项目中的线程池管理类一样,需要包含一个线程池对象,在之前我们是通过自动注入的方式,但异步线程管理类现在已经构造私有化,所以相应地也就无法获得其内部的实例化对象,所以我们就应该有一个手动获取容器对象的工具类。

public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;



    public static  T getBean(Class tClass){
        return applicationContext.getBean(tClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        applicationContext=ac;
    }
}

此类需要实现ApplicationContextAware接口,当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。

四.异步线程管理类 AsyncTaskManager

异步线程管理类理论上包含一个线程池,但我们在yam中已经配置过了,所以可以直接用SpringUtil调用ThreadPoolTaskExecutor的实例化对象即可。

public class AsyncTaskManager {



    private AsyncTaskManager() {
    }
    //获得线程池对象
    public static void executeTask(Runnable runnable){
        //获得容器里面的线程池对象
        ThreadPoolTaskExecutor taskExecutor= SpringUtil.getBean(ThreadPoolTaskExecutor.class);
        taskExecutor.execute(runnable);
    }

}

五.在controller中如何使用线程

例:

        AsyncTaskManager.executeTask(AsyncTaskFactory.emailCode());
        AsyncTaskManager.executeTask(AsyncTaskFactory.uploadFile());

你可能感兴趣的:(JAVA技术,idea,java,spring,java-ee)