Java并行执行任务的几种方案

栏目: Java · 发布时间: 5年前

内容简介:最近在排查生产环境问题,发现商品详情接口时不时会报RPC调用超时,检查代码发现接口里面查询活动耗时比较长,都是串行执行的,仔细查看发现完全可以改成并行去执行,缩短接口查询耗时。 比如我们的商品详情接口,需要展示立减、阶梯满减、团购等活动标签。需要查询三次不同的活动信息,再组装活动标签信息。如果每次查询耗时1s,按照串行的方式去调用,整个接口下来至少需要3s,整个耗时,对于我们来讲是无法接受的。其实在jdk中,给我们提供了几种非常便捷的并行执行任务的方法。

最近在排查生产环境问题,发现商品详情接口时不时会报RPC调用超时,检查代码发现接口里面查询活动耗时比较长,都是串行执行的,仔细查看发现完全可以改成并行去执行,缩短接口查询耗时。 比如我们的商品详情接口,需要展示立减、阶梯满减、团购等活动标签。需要查询三次不同的活动信息,再组装活动标签信息。如果每次查询耗时1s,按照串行的方式去调用,整个接口下来至少需要3s,整个耗时,对于我们来讲是无法接受的。其实在jdk中,给我们提供了几种非常便捷的并行执行任务的方法。

  • CountDownLatch

  • ExecutorService.invokeAll()

  • Fork/Join 分而治之 有点类似MapReduce的影子,这个有兴趣的可以自行去了解

改进方案

  • 代码例子:
private void assemblyActivityTag(CartItemDTO itemDTO){
            
        //1.查询立减活动信息,耗时1s
         
        //2.查询阶梯满减活动信息,耗时1s
        
        //3.查询团购活动信息,耗时1s
        
        //4.组装活动标签信息,耗时1s    
        
        // 串行执行下来整个耗时4s
    }
复制代码
  • CountDownLatch
private void assemblyActivityTag(CartItemDTO itemDTO){
        ExecutorService executorService = Executors.newCachedThreadPool();
        CountDownLatch latch = new CountDownLatch(3);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
            //1.查询立减活动信息
                latch.countDown();
            }
        });
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                //2.查询阶梯满减活动信息
                latch.countDown();
            }
        });
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                //3.查询团购活动信息
                latch.countDown();
            }
        });
        try {
            // 一定记得加上timeout时间,防止阻塞主线程
            latch.await(3000,TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //4.等待所有子任务完成,组装活动标签信息
         
        //5.关闭线程池
        executorService.shutdown();
    }
复制代码
  • ExecutorService.invokeAll()
private void assemblyActivityTag(CartItemDTO itemDTO) {

        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Callable<String>> tasks = Lists.newArrayList();
        tasks.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                //1.查询立减活动信息
                return null;
            }
        });
        tasks.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                //2.查询阶梯满减活动信息
                return null;
            }
        });
        tasks.add(new Callable<String>() {
            @Override
            public String call() throws Exception {
                //3.查询团购活动信息
                return null;
            }
        });

        try {
            List<Future<String>> futureList = executorService.invokeAll(tasks, 3000, TimeUnit.MILLISECONDS);
            for (Future<String> future : futureList) {
                // 获取线程执行结果
                try {
                    String activityTag = future.get();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //4.组装活动标签信息

        //5.关闭线程池
        executorService.shutdown();
    }
复制代码

以上所述就是小编给大家介绍的《Java并行执行任务的几种方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

破壁书

破壁书

邵燕君 主编、王玉玊 副主编 / 生活•读书•新知三联书店 生活书店出版有限公司 / 2018-6-1 / 88.00

*一本神奇的网络文化辞典,解读二次元、宅文化、网文、游戏、流行文化,让人大开眼界; *245个网络文化核心关键词,追本溯源,讲述背后文化演变与有趣故事,读来恍然大悟,知其然,更知其所以然; *北大中文系学术团队数年研究成果,曹文轩、韩少功、李敬泽、猫腻顾问推荐,三联生活书店花3年倾力打造; *百度 查不到、词条不过时、形式新颖丰富、文章可读性强、学术上经得起推敲,五大特点打造权威......一起来看看 《破壁书》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具