美文网首页
spring的异步处理@Async注释的简单使用

spring的异步处理@Async注释的简单使用

作者: 雨中的单车 | 来源:发表于2020-06-25 10:03 被阅读0次

    用@Async注释bean的方法将使其在单独的线程中执行,即调用方将不等待被调用方法的完成。这里说的是方法不是类。
    首先配置线程配置类
    实现org.springframework.scheduling.annotation.AsyncConfigurer.AsyncConfigurer接口,重写getAsyncExecutor()和getAsyncUncaughtExceptionHandler()方法,第一个方法配置线程池,第二个方法处理异步方法发生异常时使用的实例,此处暂未实现。

    @Configuration
    @ComponentScan("com.jbtx.Thread")
    @EnableAsync
    // 线程配置类
    public class SpringAsyncConfig implements AsyncConfigurer {
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setCorePoolSize(80);// 最小线程数
            taskExecutor.setMaxPoolSize(100);// 最大线程数
            taskExecutor.setQueueCapacity(25);// 等待队列
            //初始化
            taskExecutor.initialize();
            return taskExecutor;
        }
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(){
            return null;
        }
    }
    

    @ComponentScan("com.jbtx.Thread")这个配置一定要注意不要和别的配置扫描重叠,最好指定到标注@Async注释bean就可以了,不然在springboot配置启动时会出现嵌套异常(nested exception).

    执行异步处理的类,通过@Service注释定义一个bean。我这个程序的任务是要做海康摄像机设备状态检测,check()方法首先是抽取需要检测的设备信息,然后交给equipmentCheck()方法做具体的设备检测。原来是顺序检测,就是第一个设备处理完,才开始第二个设备检测,因为有故障的设备检测返回时间明显变长,这样我扫描一次80台左右的设备大约需要两分钟时间(其中主要是有故障的设备返回时间长导致),采用多线程异步处理方式,每次处理不需要等待返回结果,每一个请求交由一个线程独立处理,耗时基本就是一台设备检测的时间,大大缩短检测时间。

    @Service
    public class SpringAsyncService {
        //设备监测,一小时扫描一次
        public void check() {
            HIKMonitorService hikMonitorService= ResourceApplicationContext.getApplicationContext().getBean(HIKMonitorService.class);
            EquipmentInfoDto equipmentInfoDto;
            while (true) {
                try {
                    //获取要监测海康设备列表
                    List equipmentList = hikMonitorService.getEquipmentList();
                    for (int i = 0; i < equipmentList.size(); i++) {
                        equipmentInfoDto = (EquipmentInfoDto) equipmentList.get(i);
                        equipmentCheck(equipmentInfoDto);
                        //equipmentCheck(equipmentInfoDto);
                    }
                    //暂停一小时再次执行
                    Thread.sleep(3600000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        @Async
        public void equipmentCheck(EquipmentInfoDto equipmentInfoDto){
            HIKMonitorService hikMonitorService= ResourceApplicationContext.getApplicationContext().getBean(HIKMonitorService.class);
            hikMonitorService.equipmentCheck(equipmentInfoDto);
        }
    }
    

    其中ResourceApplicationContext类是为了在异步处理方法中获取spring已经预先加载的类。因为SpringAsyncService是单独扫描加载的类,所以他获取不到spring已经预先加载的类。
    最后在springboot的启动类main方法中增加以下代码完成异步处理方法加载和运行

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringAsyncService.class);
            SpringAsyncService springAsyncService = context.getBean(SpringAsyncService.class);
            springAsyncService.check();
    

    相关文章

      网友评论

          本文标题:spring的异步处理@Async注释的简单使用

          本文链接:https://www.haomeiwen.com/subject/lpojfktx.html