精华内容
下载资源
问答
  • Java并行执行任务的几种方案

    千次阅读 2019-05-15 08:15:04
    最近在排查生产环境问题,发现商品详情接口时不时会报RPC调用超时,检查代码发现接口里面查询活动耗时比较长,都是串行执行的,仔细查看发现完全可以改成并行执行,缩短接口查询耗时。 比如我们的商品详情接口,...

    背景

    最近在排查生产环境问题,发现商品详情接口时不时会报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();
        }
    复制代码

    注意点和区别

    • 在使用CountDownLatch,尽可能使用线程安全的容器去处理子线程的返回值,避免多线程情况下,出现脏数据。
    • 如果想知道每个子线程的对应的返回值,ExecutorService.invokeAll()方式,是没法区分的,只能依赖返回值的顺序去匹配。
    • 使用上面2种方式时,切记设置超时时间,防止子任务执行时间过长,阻塞主线程任务
    • 线程池用完结束,记得shutdown()

    总结

    鉴于作者才疏学浅,文中不足之处还望你不吝斧正,如有雷同纯属巧合

    展开全文
  • 最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf”(实际上比预期花了不少精力),包含分布式架构、...

    如何高效的学习MyBatis源码呢?

    市面上真正适合学习的MyBatis资料太少,有的书或资料虽然讲得比较深入,但是语言晦涩难懂,大多数人看完这些书基本都是从入门到放弃。学透MyBatis源码难道就真的就没有一种适合大多数同学的方法吗?

    在这分享一份精通MyBatis学习指南(学习文档+视频讲解+Xmind思维导图),这份学习指南从MyBatis源码的角度,深入浅出,从入门到精通,同时介绍一些MyBatis的高级用法,并挖掘MyBatis源码中使用的设计模式等

    MyBatis学习文档

    1. mybatis的基本用法
    2. mybatis的体系结构
    3. 深入mybatis的配置文件
    4. 深入Mapper XML映射文件
    5. mybatis的关联映射和动态SQL
    6. mybatis的事务管理和缓存机制
    7. mybatis的注解配置
    8. Spring整合mybatis

    拿到美团、快手offer后收到阿里三面通知,竟被MyBatis挡住了去路

    Mybatis思维导图

    1. mybatis简介
    2. 与hibernate对比
    3. mybatis框架整体设计
    4. mybatis源码的几个主要部件
    5. XML映射配置文件
    6. mybatis的优缺点
    7. Spring整合mybatis
    8. mapper的xml文件
    9. 动态SQL
    10. resultMap子元素
    11. 鉴别器discriminator
    12. 插件拓展
    13. 常用注解

    拿到美团、快手offer后收到阿里三面通知,竟被MyBatis挡住了去路

    写在最后

    作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动?

    就目前大环境来看,跳槽成功的难度比往年高很多。一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。

    最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf”(实际上比预期多花了不少精力),包含分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货!

    由于篇幅有限,为了方便大家观看,这里以图片的形式给大家展示部分的目录和答案截图!有需要的朋友可以戳这里免费获取

    Java经典面试问题(含答案解析)

    阿里巴巴技术笔试心得

    阿里巴巴技术笔试心得

    [外链图片转存中…(img-M1RpSwd0-1625929244957)]

    展开全文
  • java并行执行多任务

    万次阅读 2014-02-24 17:26:52
    java并行执行多任务: 最近做项目中,有个任务需要实现并发编程,个人参考了下网上的实现,自己实现了下并发方法,并且增加了简单的说明,希望的有需要的朋友有些帮助。 import java.util.UUID; import java....

    java并行执行多个任务:

    最近做项目中,有个任务需要实现并发编程,个人参考了下网上的实现,自己实现了下并发方法,并且增加了简单的说明,希望的有需要的朋友有些帮助。


     
    import java.util.UUID;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 测试监控类
     * 
     * @author
     * 
     */
    public class WatchThread {
    	
    	private String name = UUID.randomUUID().toString();
    
    	/**
    	 * 测试函数
    	 * 
    	 * @throws InterruptedException
    	 */
    	public void testThread() throws InterruptedException {
    		int threadNum = 10;
    		// 初始化countDown
    		CountDownLatch threadSignal = new CountDownLatch(threadNum);
    		// 创建固定长度的线程池
    //		Executor executor = Executors.newFixedThreadPool(threadNum);
    		//此处不可以用接口 需要使用Executor的实现类 ExecutorService  Executor未提供shutdown等方法
    		ExecutorService executor = Executors.newFixedThreadPool(threadNum);
    		for (int i = 0; i < threadNum; i++) { // 开threadNum个线程
    			Runnable task = new TestThread(threadSignal);
    			// 执行
    			executor.execute(task);
    			
    		}
    		threadSignal.await(); // 等待所有子线程执行完
    		//固定线程池执行完成后 将释放掉资源 退出主进程
    		executor.shutdown();//并不是终止线程的运行,而是禁止在这个Executor中添加新的任务
    		// do work end
    		//退出主进程
    		System.out.println(Thread.currentThread().getName() + "+++++++结束.");
    	}
    
    	/**
    	 * 测试函数
    	 */
    	public static void main(String[] args) throws InterruptedException {
    		WatchThread test = new WatchThread();
    		test.testThread();
    	}
    
    	/**
    	 * 
    	 * @author wangmuming
    	 * 此可以做完内部类 也可以不做未内部类
    	 * 作为内部类的时候 有一个好处 就是可以直接引用给类的主对象的成员变量 如此处的name
    	 * 当然
    	 */
    	private class TestThread implements Runnable {
    		private CountDownLatch threadsSignal;
    
    		public TestThread(CountDownLatch threadsSignal) {
    			this.threadsSignal = threadsSignal;
    		}
    		
    
    		public void run() {
    			System.out.println(Thread.currentThread().getName() + "开始..." + name);
    			System.out.println("开始了线程::::" + threadsSignal.getCount());
    			
    			// do shomething
    		
    			//核心处理逻辑
    			
    		//	用到成员变量name作为参数
    			
    			// 线程结束时计数器减1
    			threadsSignal.countDown();//必须等核心处理逻辑处理完成后才可以减1
    			System.out.println(Thread.currentThread().getName() + "结束. 还有"
    					+ threadsSignal.getCount() + " 个线程");
    		}
    	}
    
    }

    
    

    
    

    执行结果:


    pool-1-thread-1开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::10
    pool-1-thread-1结束. 还有9 个线程
    pool-1-thread-2开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::9
    pool-1-thread-2结束. 还有8 个线程
    pool-1-thread-3开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::8
    pool-1-thread-3结束. 还有7 个线程
    pool-1-thread-4开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    pool-1-thread-5开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::7
    开始了线程::::7
    pool-1-thread-4结束. 还有6 个线程
    pool-1-thread-5结束. 还有5 个线程
    pool-1-thread-10开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::5
    pool-1-thread-6开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    pool-1-thread-9开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::4
    pool-1-thread-9结束. 还有3 个线程
    pool-1-thread-8开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::3
    pool-1-thread-8结束. 还有2 个线程
    pool-1-thread-7开始...aaa917dc-bd69-4438-9bb1-0051e5c62984
    开始了线程::::2
    pool-1-thread-7结束. 还有1 个线程
    开始了线程::::4
    pool-1-thread-10结束. 还有4 个线程
    pool-1-thread-6结束. 还有0 个线程
    main+++++++结束.

    展开全文
  • 本篇文章主要介绍了java实现线程之定时器任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Java多线程并行处理任务的实现

    万次阅读 2019-04-20 21:08:02
    Java多线程并行处理任务的实现 在实际项目开发的过程中,遇到过需要处理一个由个子任务组成的任务的问题.顺序处理起来会造成响应时间超长,用户体验不好的问题.我想到一个解决方案,即使用线程并行处理子任务.思路...

    Java多线程并行处理任务的实现

    在实际项目开发的过程中,遇到过需要处理一个由多个子任务组成的任务的问题.顺序处理起来会造成响应时间超长,用户体验不好的问题.我想到一个解决方案,即使用多线程并行处理子任务.思路就是使用ThreadPoolExecutor线程池,然后使用一个list保存所有线程的实例引用.以下是代码实现.

    以下是代码实现

    FactorialCalculator 类:用于实现具体的业务处理

    package ThreadTask;
    
    import java.util.concurrent.Callable;
    
    public class FactorialCalculator implements Callable<Integer> {
        private int number;
    
        public FactorialCalculator(int number) {
            this.number = number;
        }
    
        //计算阶乘
        public Integer call() throws Exception {
            Integer result = 1;
            if (number == 0 || number == 1)
                result = 1;
            else {
                for (int i = 2; i <= number; i++) {
                    result *= i;
                    //为了演示效果,休眠20ms
                    Thread.sleep(20);
                }
            }
            System.out.printf("线程:%s," + number + "!= %d\n", Thread.currentThread().getName(), result);
            return result;
        }
    
    }
    

    Main 类:用于实现多线程任务的实现和处理

    import ThreadTask.FactorialCalculator;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.ThreadPoolExecutor;
    
    
    public class Main {
    
        public static void main(String[] args) {
            Long startTime = System.currentTimeMillis();
            ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);//创建只有2个线程的线程池
            //存放结果的列表
            List<Future<Integer>> resultList = new ArrayList<>();
            //通过Random类生成一个随机数生成器
            Random random = new Random();
            for (int i = 0; i < 10; i++) {
                int number = random.nextInt(10);
                FactorialCalculator calculator = new FactorialCalculator(number);
                Future<Integer> result = executor.submit(calculator);
                resultList.add(result);
            }
            //创建一个循环来监控执行器的状态
            try {
                while (executor.getCompletedTaskCount() < resultList.size()) {
                    System.out.printf("\n已完成的线程数量: %d\n", executor.getCompletedTaskCount());
                    for (int i = 0; i < resultList.size(); i++) {
                        Future<Integer> result = resultList.get(i);
                        System.out.printf("第 %d 个线程 : 是否完成:%s\n", i, result.isDone());
                    }
                    Thread.sleep(50);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("全部线程执行结束");
            try {
                for (int i = 0; i < resultList.size(); i++) {
                    Future<Integer> result = resultList.get(i);
                    Integer number = null;
                    number = result.get();
                    System.out.printf("第 %d 个线程 执行结果是: %d\n", i, number);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            executor.shutdown();
            Long endTime = System.currentTimeMillis();
            System.out.println("使用时间 = [" + (endTime - startTime) + "]");
        }
    }
    
    展开全文
  • java定时执行多任务和quartz定时执行多任务
  • java多任务并行

    2019-10-12 16:43:10
    https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html https://www.oracle.com/technetwork/cn/articles/java/fork-join-422606-zhs.html
  • 主要介绍了SpringBoot 多任务并行+线程池处理的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Java多任务并行执行(带前置任务)

    千次阅读 2017-06-13 10:49:00
    出现需求在登录时,需要向服务器个接口请求程序所需数据。有些任务B必须等待任务A请求数据返回后在请求。
  • 主要介绍了线程并发ScheduledExecutorService类,设置 ScheduledExecutorService ,2秒后,在 1 分钟内每 10 秒钟蜂鸣一次
  • 详细描述了Jenkins安装、环境配置以及多任务并行设置。 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1)持续的软件版本发布/测试项目; 2)监控外部调用执行的工作。
  • 线程并行执行,然后汇总结果、线程并行执行,汇总结果。 MultiThread,ResultVo> multiThread = new MultiThread,ResultVo>(threadList){ @Override public List<ResultVo> outExecute(int currentThread...
  • java并行

    千次阅读 2019-08-13 15:55:58
    java7之前,处理并行数据非常麻烦. 第一:你得明确的把包含的数据结构分成若干子部分. 第二:你要给每个子部分分配独立的线程. 第三:你需要在恰当的时候对他们进行同步,来避免不希望出现的竞争条件,等待所有线程完成,...
  • java中两任务并行运行 当我们用Java编写线程应用程序时,我们倾向于使用“ Runnable ”接口来实现线程类。 您的类必须简单地实现此接口并覆盖run方法。 对于琐碎的用例,我们可以通过调用“ start”方法直接...
  • 本篇文章主要介绍了SpringBoot CountDownLatch多任务并行处理的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • java并行执行任务demo

    千次阅读 2018-02-01 16:30:38
    在一个方法中同时调用个方法或者服务,并等待所有结果返回 package com.test.demo; import org.junit.Test; import java.util.concurrent.CompletableFuture; public class TestFuture { @Test public ...
  • java并行查询数据库什么是并行数据库流? 阅读这篇文章,了解如何使用并行流和Speedment并行处理数据库中的数据。 在许多情况下,并行流可能比通常的顺序流快得。 随着Java 8的引入,我们得到了期待已久的Stream...
  • 谈到并行,我们可能最先想到的是线程,个线程一起运行,来提高我们系统的整体处理速度;为什么使用个线程就能提高处理速度,因为现在计算机普遍都是多核处理器,我们需要充分利用cpu资源;如果站的更高一点来看...
  • Java线程池并发执行多任务

    万次阅读 2017-06-28 23:14:11
    Java在语言层面提供了线程的支持,线程池能够避免频繁的线程创建和销毁的开销,因此很时候在项目当中我们是使用的线程池去完成线程的任务Java提供了Executors 框架提供了一些基础的组件能够轻松的完成...
  • Java 7 之前,如果想要并行处理一个集合,我们需要以下几步 1. 手动分成几部分 2. 为每部分创建线程 3. 在适当的时候合并 并且还需要关注个线程之间共享变量的修改问题。而 Java8 为我们提供了并行流,可以...
  • 适用场景 问题抽象:线程处理集合,返回...预期目的:并行处理业务逻辑,按顺序返回处理结果 处理方案:线程处理返回结果Futrue,对Future保证顺序即可得到有序的结果(不考虑资源共享) 在这里插入代码片 ...
  • Java 中的并行处理

    2021-07-14 10:56:47
    本文是一个短文章,介绍Java 中的并行处理。 说明:10分钟读完的文章我称之为短文章,适合快速阅读。 2.知识 并行计算(parallel computing)一般是指许多指令得以同时进行的计算模式。在同时进行的前提下,可以将...
  • Java使用Fork/Join框架来并行执行任务

    千次阅读 2019-01-03 17:12:35
    现代的计算机已经向CPU方向发展,即使是普通的PC,甚至现在的智能手机、多核处理器已被广泛应用。在未来,处理器的核心数将会发展的越来越。 虽然硬件上的多核CPU已经十分成熟,但是很应用程序并未这种多核...
  • java多线程详解(并发,并行,同步)

    万次阅读 2017-07-04 10:30:41
    引子:前面讲到程序的运行流程的时候,说程序在没有流程控制前提下,代码都是从上而下逐行执行的。 需求:现在需要设计一个程序想要完成边运行游戏,边播放歌的功能,怎么设计? 要解决上述问题,咱们得使用进程或者...
  • java 定时任务串行并行

    千次阅读 2016-05-22 17:45:38
    近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,所以我都将结合 spring框架来介绍。 一.分类...
  • 关于Java多线程是否并行执行的问题

    千次阅读 2019-08-20 11:13:32
    理论上,Java线程在CPU(或者内核)情况下,应该是并行处理的,即将个线程均匀分布到个CPU上去执行,这样的话,理论上做"任务"只需要花"做一个任务"的时间。 那么实际情况怎样呢? 下图是我的电脑...
  • 1)聚合个异步任务 需求:个tab页包含不同的表格数据,并且带分页,页面首次加载时需要显示第一页数据,并且在tab顶上显示总量,如下图所示: 各个表格数据从es中查询,涉及到计算,此处可以让前端调用个...
  • 线程编程过程中,遇到这样的情况,主线程需要等待个子线程的处理结果,才能继续运行下去。个人给这样的子线程任务取了个名字叫并行任务。对于这种任务,每次去编写代码加锁控制时序,觉得太麻烦,正好朋友提到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 123,053
精华内容 49,221
关键字:

java并行执行多任务

java 订阅