轻识Logo
目录

    面试问,@EnableAsync 和 @Async

    在我们的日常开发中,我们偶尔会遇到在业务层中我们需要同时修改多张表的数据并且需要有序的执行,如果我们用往常的同步的方式,也就是单线程的方式来执行的话,可能会出现执行超时等异常造成请求结果失败,及时成功,前端也需要等待较长时间来获取响应结果,这样不但造成了用户体验差,而且会经常出现请求执行失败的问题,在这里我们一般会采用3种方式来处理,如下所示:

    在采用三种方式之前,我们所有来观察一下使用同步的方式实现的结果:

    1.我们定义一个TestController,如下所示:

    @RestController
    public class TestController {
     
        @Autowired
        private TestService service;

        /**
         * 使用传统方式测试
         */

        @GetMapping("/test")
        public void test() {
            System.out.println("获取主线程名称:" + Thread.currentThread().getName());
            service.serviceTest();
            System.out.println("执行成功,返回结果");
        }
    }

    2. 我们定义TestService,如下所示:

    @Service
    public class TestAsyncService {
     
        public void serviceTest() {
                // 这里执行实际的业务逻辑,在这里我们就是用一个简单的遍历来模拟
                Arrays.stream(new int[]{1,2,3,4,5,6,7,8,9,10}).forEach( t -> {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("获取number为:" + t) ;
                });
        }
    }

    我们执行请求http://localhost:8888/test,结果显示如下:

    接下来我们采用我们所说的3种方式来实现:

    1.使用线程池的方式来实现

    1)定义TestAsyncController中的test()方法,如下所示:

    @RestController
    public class TestAsyncController {
     
        @Autowired
        private TestAsyncService asyncService;
        
        /**
         * 使用传统方式测试
         */

        @GetMapping("/test")
        public void test() {
            System.out.println("获取主线程名称:" + Thread.currentThread().getName());
            /**
             *  这里也可以采用以下方式使用,但是使用线程池的方式可以很便捷的对线程管理(提高程序的整体性能),
             *  也可以减少每次执行该请求时都需要创建一个线程造成的性能消耗
             *  new Thread(() ->{
             *  run方法中的业务逻辑
             *  })
             */

     
            /**
             * 定义一个线程池
             * 核心线程数(corePoolSize):1
             * 最大线程数(maximumPoolSize): 1
             * 保持连接时间(keepAliveTime):50000
             * 时间单位 (TimeUnit):TimeUnit.MILLISECONDS(毫秒)
             * 阻塞队列 new LinkedBlockingQueue()
             */

            ThreadPoolExecutor executor = new ThreadPoolExecutor(1,5,50000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
            // 执行业务逻辑方法serviceTest()
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    asyncService.serviceTest();
                }
            });
            System.out.println("执行完成,向用户响应成功信息");
        }
    }

    2)定义TestAsyncServiceTestService中的test()相同,在这就不显示了;

    3)查看运行结果:

    我们发现在主线程中使用线程池中的线程来实现,程序的执行结果表明,主线程直接将结果进行了返回,然后才是线程池在执行业务逻辑,减少了请求响应时长。

    2. 使用注解@EnableAsync和@Async来实现

    (1)虽然这样实现了我们想要的结果,但是,但是我们发现如果我们在多个请求中都需要这种异步请求,每次都写这么冗余的线程池配置会不会,这种问题当然会被我们强大的spring所观察到,所以spring为了提升开发人员的开发效率,使用@EnableAsync来开启异步的支持,使用@Async来对某个方法进行异步执行。

    TestAsyncController如下所示:

    @RestController
    public class TestAsyncController {
     
        @Autowired
        private TestAsyncService asyncService;
     
        /**
         * 使用@Async来实现
         */

        @GetMapping("/test")
        public void test() {
            System.out.println("获取主线程名称:" + Thread.currentThread().getName());
            // 异步调用
            asyncService.serviceTest();
            System.out.println("执行完成,向用户响应成功信息");
        }

    (2)TestAsyncService如下所示:

    @Service
    @EnableAsync
    public class TestAsyncService {
     
     
        /**
         * 采用异步执行
         */

        @Async
        public void serviceTest() {
                // 这里执行实际的业务逻辑,在这里我们就是用一个简单的遍历来模拟
                Arrays.stream(new int[]{1,2,3,4,5,6,7,8,9,10}).forEach( t -> {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("获取number为:" + t) ;
                });
        }

    (3)执行结果如下:

    结果与使用线程池的结果一致,但是简化了我们编写代码的逻辑,@Async注解帮我们实现了创建线程池的繁琐,提高了我们的开发效率。

    3. 使用消息队列(mq)来实现

    当我们涉及的请求在业务逻辑中一次性操作很多很多的数据,例如:一个请求执行相关业务操作后,将操作日志插入到数据库中,我们可以使用@Async来实现,但是这样增加了业务和非业务关系的冗余性(同时如何并发量很大,我们使用@Async处理,无法提升我们系统的整体系统,这样很容易造成服务器宕机),所以我们对于这种情况,我们会采用mq来实现,将业务逻辑和非业务逻辑进行隔离执行,互不影响,非业务逻辑不会影响到执行业务逻辑的结果和主机性能,对于mq的处理,我会在后续添加。

    来源:blog.csdn.net/qq_38796327/article/details/90599867

    ——————END——————

    欢迎关注“Java引导者”,我们分享最有价值的Java的干货文章,助力您成为有思想的Java开发工程师!

    浏览 7
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报
    三流面试问技术,二流面试问平台,一流面试……
    三太子敖丙
    0
    三流面试问技术,二流面试问平台,一流面试……
    Hollis
    0
    三流面试问技术,二流面试问平台,一流面试……
    Java进阶学习交流
    0
    三流面试问技术,二流面试问平台,一流面试…
    HelloGitHub
    0
    【面朝大厂】k8s面试问什么?
    程序员面试吧
    0
    Async
    Thispluginallowstoeasilycodeverylong-lastingloopsinanasynchronouswaytoavoidlosingthebrowserresponsiv
    Async
    0
    SpringBoot @Async:魔法和陷阱
    小哈学Java
    0
    Async
    This plugin allows to easily code very long-lastin
    Async
    0
    面试问烂的 Spring AOP 、MVC 原理
    泥瓦匠BYSocket
    0
    点赞
    评论
    收藏
    分享

    手机扫一扫分享

    举报

    深圳SEO优化公司岳阳网站推广方案哪家好新余网站建设西乡外贸网站制作报价平湖高端网站设计推荐漳州关键词按天收费价格宿州网站建设公司泰安建网站多少钱赤峰seo网站优化哪家好潮州网站seo优化多少钱崇左SEO按天计费西安关键词按天收费公司海北网站seo优化哪家好贺州seo优化哪家好大丰百度爱采购多少钱临沂网站开发价格菏泽百度竞价哪家好周口设计网站池州网页制作多少钱珠海网站制作设计哪家好海南设计网站价格茂名seo优化价格永新SEO按天扣费价格凉山百度标王多少钱永新网站改版报价平湖seo优化推荐襄樊seo哪家好张家界网站推广方案价格安顺网站优化按天计费推荐喀什网站优化推广哪家好濮阳网站制作报价歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

    深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化