精华内容
下载资源
问答
  • 我一直不太明白,多线程是指多个线程同时执行多个任务 还是指多个线程同时执行个任务?求解。如果执行 同个任务肯定要加锁。
  • 一个线程执行多个任务,要按照顺序执行import java.util.concurrent.ArrayBlockingQueue;/** * 一个线程执行多个任务,要按照顺序执行,怎么去实现? * 分析: * 多个人任务-->线程 * 要按照顺序执行--》就需要...

    一个线程执行多个任务,要按照顺序执行

    import java.util.concurrent.ArrayBlockingQueue;
    
    /**
     * 一个线程执行多个任务,要按照顺序执行,怎么去实现?
     * 分析:
     *      多个人任务-->线程
     *      要按照顺序执行--》就需要排队,那就是队列
     *       一个给任务,一个执行任务--》涉及一个生产一个消费
     *      过渡:需要容器装任务来存储任务
     *      有两个线程,一放一取不是原子操作,所以涉及线程安全问题
     * @author qfl
     * 扩展:
     * 1)怎么实现一个阻塞式对列结构?
     * 2)怎么实现一个LruCache缓存结构(不依托于LikedList,HashMap来实现)?
     * lru:最近最少算法
     * 
     * 扩展问题:
     *
     */
    public class TestIOBlocking {
        static int m=0;
        //主线程
        public static void main(String[] args) {
            System.out.println("开始!");
            //生产任务的
            TestExecutor t=new TestExecutor();
            for(int i=0;i<20;i++) {
                t.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("test"+TestIOBlocking.m++);
                    }
                }); 
            }
    
        } 
    }
    class TestExecutor{
        public TestExecutor() {
            //创建对象就执行
            thread.start();
        }
        private static workThread thread=new workThread();
        //存储任务的容器,先设定存3个任务,这是一个阻塞的队列
        private static ArrayBlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>(3);
    
        //工作线程
        static class workThread extends Thread{
            @Override
            public void run() {
                    //执行的任务,反复的取
                while(TestIOBlocking.m<=19) {
                    try {
                        Runnable r=queue.take();//阻塞方法
                        r.run();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        //取任务的方法
        public void execute(Runnable r) {
            try {
                queue.put(r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    展开全文
  • 1、首先需要理解CountDownLatch: ...CountDownLatch的作用也是如此,在构造CountDownLatch的时候需要传入一个整数n,在这个整数“倒数”到0之前,主线程需要等待在门口,而这个“倒数”过程则是由各个执行线程...

    1、首先需要理解 CountDownLatch:

    CountDownLatch中count down是倒数的意思,latch则是门闩的含义。整体含义可以理解为倒数的门栓,似乎有一点“三二一,芝麻开门”的感觉。CountDownLatch的作用也是如此,在构造CountDownLatch的时候需要传入一个整数n,在这个整数“倒数”到0之前,主线程需要等待在门口,而这个“倒数”过程则是由各个执行线程驱动的,每个线程执行完一个任务“倒数”一次。总结来说,CountDownLatch的作用就是等待其他的线程都执行完任务,必要时可以对各个任务的执行结果进行汇总,然后主线程才继续往下执行。

            CountDownLatch主要有两个方法:countDown()和await()。countDown()方法用于使计数器减一,其一般是执行任务的线程调用,await()方法则使调用该方法的线程处于等待状态,其一般是主线程调用。这里需要注意的是,countDown()方法并没有规定一个线程只能调用一次,当同一个线程调用多次countDown()方法时,每次都会使计数器减一;另外,await()方法也并没有规定只能有一个线程执行该方法,如果多个线程同时执行await()方法,那么这几个线程都将处于等待状态,并且以共享模式享有同一个锁。

    2、代码实列、我的项目是要处理一批数据然后插入到数据库表中之前单线程处理的时候因为涉及到数据的加工筛选然后在把符合的数据插入表中,现在我先把需要处理的数据一个list把它每500个分为一组,然后开启一个线程去处理插入数据库表中、最后所有分组的数据也就是多个线程把数据都处理完之后主线程返回处理结果。

       //每个线程处理的数据量
        private static final int count = 500;
    
        //定义线程池数量为8,每个线程处理500条数据
        private static ExecutorService execPool = Executors.newFixedThreadPool(8);
    
    
    
     /**
         * 多线程批量执行插入,百万数据需要大约不到20秒   64位4核处理
         * 需要插入数据库的数据  limodel
         *
         * @return
         */
      public JsonData batchAddData(List<Entity> limodel) {
            JsonData jd = new JsonData();
            try {
                if (limodel.size() <= count) {
                    threadsSignal = new CountDownLatch(1);
                    //往线程池里面放创建的子线程
                    execPool.submit(new InsertDate(limodel));
                } else {
                    List<List<Entity>> li = createList(limodel, count);
                    threadsSignal = new CountDownLatch(li.size());
                    for (List<Entity> liop : li) {
                        execPool.submit(new InsertDate(liop));
                    }
                }
                //主线程调用了await()方法,此时主线程将在此处等待创建的多个子线程执行完任务之后才继续往下执行
                threadsSignal.await();
            } catch (Exception e) {
                // TODO: handle exception
                log.error("异常:" + e.toString());
                //execPool.shutdownNow();
            }
            return jd;
        }
    
        /**
         * 数据拆分
         *
         * @param targe
         * @param size
         * @return
         */
        public static List<List<Entity>> createList(List<Entity> targe, int size) {
            List<List<Entity>> listArr = new ArrayList<List<Entity>>();
            //获取被拆分的数组个数
            int arrSize = targe.size() % size == 0 ? targe.size() / size : targe.size() / size + 1;
            for (int i = 0; i < arrSize; i++) {
                List<Entity> sub = new ArrayList<Entity>();
                //把指定索引数据放入到list中
                for (int j = i * size; j <= size * (i + 1) - 1; j++) {
                    if (j <= targe.size() - 1) {
                        sub.add(targe.get(j));
                    }
                }
                listArr.add(sub);
            }
            return listArr;
        }
    
    
        /**
         * 内部类,开启线程批量保存数据
         */
        class InsertDate extends Thread {
    
            List<Entity> lientity = new ArrayList<Entity>();
    
            public InsertDate(List<Entity> list1) {
               try{
                  if (list1.size() > 0 && list1 != null) {
                     for (Entity pu : list1) {
                        //数据处理逻辑省略...........
                     }
                   }
               }catch(Exception e){
                 log.error("格式化数据异常:" + e); 
               }
                
            }
    
    
            public void run() {
                try {
                    dao.save(lientity);
                } catch (Exception e) {
                    log.error("多线程插入数据异常:" + e);
                } finally {
                    //每开启一个线程计数器减一,注意保证线程执行是否异 
                    //常都要进行减一,不然的话主线程会一直等threadsSignal等于0的时候才开始执行下面 
                    //操作
                   threadsSignal.countDown();
                }
            }
        }
    

     CountDownLatch详解

    展开全文
  • 问题最近我在处理批数据,用多线程来处理,我想知道大概多久能处理完。比如我先用多线程处理 100 条数据,统计下用时,然后根据总的数据量就可以大概估算出处理完这批数据要多久。使用 CountDownLatch 计时思路:...

    问题

    最近我在处理一批数据,用多线程来处理,我想知道大概多久能处理完。比如我先用多线程处理 100 条数据,统计下用时,然后根据总的数据量就可以大概估算出处理完这批数据要多久。

    使用 CountDownLatch 计时

    思路:用两个 CountDownLatch 倒计时锁:开始计时锁,任务结束计时锁。开始计时锁在子线程任务开始时通过 await() 阻塞所有子线程,然后在主线程中通过 CountDownLatch 控制所有子线程同时开始获取开始时间;任务结束计时锁 CountDownLatch 在每个子线程执行完后都 countDown 一次,直到所有子线程执行完,主线程开始记录所有任务执行结束时间。

    示例代码

    /**
     * ClassName: ThreadTiming <br/>
     * Function: 计算多个线程任务执行完后的用时<br/>
     *
     * @author gary.liu
     * @date 2017/6/24
     */
    public class ThreadTiming {
    
        private int nThread;
    
        private CountDownLatch startGate;
        private CountDownLatch endGate;
    
        public ThreadTiming(int nThread, CountDownLatch startGate, CountDownLatch endGate) {
    
            this.nThread = nThread;
            this.startGate = startGate;
            this.endGate = endGate;
        }
    
        class worker implements Runnable {
    
            public void run() {
                try {
                    startGate.await();
                    Random random = new Random();
                    int num = random.nextInt(500) + 500;
                    System.out.println(Thread.currentThread().getName() + " start and sleep: " + num + "ms");
                    Thread.sleep(num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    endGate.countDown();
                }
            }
        }
    
        public long timeTasks() {
    
            for(int i = 0; i < nThread; i++){
                Thread thread = new Thread(new worker());
                thread.start();
            }
    
            long start = System.currentTimeMillis();
            //所有阻塞的任务同时开始
            startGate.countDown();
            try {
                //主线程阻塞,等待其他所有 worker 线程完成后再执行
                endGate.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long end = System.currentTimeMillis();
            System.out.println("用时: " + (end - start) + "ms");
    
            return end - start;
        }
    
        public static void main(String[] args) {
    
            int nThread = 5;
            CountDownLatch startGate = new CountDownLatch(1);
            CountDownLatch endGate = new CountDownLatch(nThread);
    
            new ThreadTiming(nThread, startGate, endGate).timeTasks();
    
        }
    }
    

    运行结果

    Thread-4 start and sleep: 897ms
    Thread-0 start and sleep: 811ms
    Thread-2 start and sleep: 678ms
    Thread-3 start and sleep: 582ms
    Thread-1 start and sleep: 576ms
    用时: 903ms

    可以看到总用时比花费最长时间的线程任务时间多一点,随着并发量越大,达到可同时并发执行的线程最大数后,用时会越久。下面线程池的例子,限制了并发线程数后,可以明显的看到这一点。

    用栅栏 CyclicBarrier 应该也是可以实现的,也可以和wait()、notifyAll() 混用来实现 ,这里就不在具体展开了。

    使用线程池中方法计时

    线程池中提供了监控线程池运行的一些方法,这里通过线程池的 isTerminated() 方法不断检测,线程池中的任务是否都执行完成了,来获取所有任务结束时间。

    示例代码

    public class ExecuteOrderPractice {
    
        public void orderPractice(){
            ExecutorService executorService = Executors.newFixedThreadPool(3);
            long start = System.currentTimeMillis();
            for(int i = 0; i < 5; i++){
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        try{
                            Thread.sleep(1000);
                            System.out.println(Thread.currentThread().getName() + " do something");
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                });
            }
    
            executorService.shutdown();
    
            while(true){
                if(executorService.isTerminated()){
                    //System.out.println("Finally do something ");
                    long end = System.currentTimeMillis();
                    System.out.println("用时: " + (end - start) + "ms");
                    break;
                }
    
            }
        }
    
        public static void main(String[] args){
            new ExecuteOrderPractice().orderPractice();
    
        }
    }

    运行结果

    pool-1-thread-1 do something
    pool-1-thread-3 do something
    pool-1-thread-2 do something
    pool-1-thread-1 do something
    pool-1-thread-3 do something
    用时: 2010ms

    参考资料

    《Java 并发编程实战》

    展开全文
  • 描述:假如有5w条数据,数据格式是商品id、商品的价格,在5w数据中,可以重复...能不能用将这5w数据分配给5个线程,分别处理,还要保证每个线程处理都不相同。 小弟,没接触过线程,特请教大神!,最好能贴上你的代码!
  • 多线程开发中,经常会遇到这样的问题,比如,一个线程需要其他的一些辅助线程完成指定的一些任务后才能开 启。 类似于一个主线程正在运行,他需要其他分支线程完成一些任务后才能激活他来启动剩下的任务,这里就...

    在多线程开发中,经常会遇到这样的问题,比如,一个线程需要其他的一些辅助线程完成指定的一些任务后才能开

    启。 类似于一个主线程正在运行,他需要其他分支线程完成一些任务后才能激活他来启动剩下的任务,这里就可以使用

    Java自带的CountDownLatch这个类来帮我们实现这样的效果。   这个类初始化的时候会指定一个数字,这就是需要等

    待的资源的数量,每一个资源到位的时候,就调用他的countDown函数,这样就会将资源减一,知道这个资源数字变成

    0的时候 ,就会叫醒主线程,来完成剩下的功能,下面我们就使用一个例子来说明这样的情况。


    package com.bird.concursey.charpet4;
    
    import java.util.concurrent.CountDownLatch;
    
    public class Videoconference implements Runnable {
    	
    	private CountDownLatch controller;
    	
    	/**
    	 * Implement the constructor of the class that initializes the CountDownLatch
    attribute. The Videoconference class will wait for the arrival of the number of
    participants received as a parameter.
    	 * @param number
    	 */
    	public Videoconference(int number) {
    		controller = new CountDownLatch(number);
    	}
    	
    	public void arrive(String name) {
    		System.out.printf("%s has arrived.",name);
    		controller.countDown();
    		System.out.printf("VideoConference: Waiting for %d participants.\n",controller.getCount());
    	}
    	
    	@Override
    	public void run() {
    		System.out.printf("VideoConference: Initialization: %d participants.\n",controller.getCount());
    		try {
    			controller.await();
    			System.out.printf("VideoConference: All the participants have come\n");
    			System.out.printf("VideoConference: Let's start...\n");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    



    package com.bird.concursey.charpet4;
    
    import java.util.concurrent.TimeUnit;
    
    public class Participant implements Runnable {
    	
    	private Videoconference videoConference;
    	
    	private String name;
    	
    	public Participant(Videoconference videoConference, String name) {
    		this.videoConference = videoConference;
    		this.name = name;
    	}
    
    
    	@Override
    	public void run() {
    		long duration=(long)(Math.random()*10);
    		try {
    			TimeUnit.SECONDS.sleep(duration);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		videoConference.arrive(name);
    	}
    	
    	public static void main(String[] args) {
    		//Create a Videoconference object named conference that waits for 10 participants.
    		Videoconference videoCOnference = new Videoconference(10);
    		Thread threadConference = new Thread(videoCOnference);
    		threadConference.start();
    		
    		for(int i = 0; i < 10; i++) {
    			Participant participant = new Participant(videoCOnference, "participant" + i);
    			Thread t = new Thread(participant);
    			t.start();
    		}
    	}
    
    }
    


    展开全文
  • 多任务多线程

    千次阅读 热门讨论 2017-12-03 13:50:17
    前言前段时间,我们部门组织了学习Linux系统的安装与命令学习 Linux系统是UNIX操作系统的克隆版,是Unix的开源...多任务多任务指的是台电脑上可同时运行多个应用程序(也叫多个进程),是多个任务共享处理资
  • springmvc定时任务同时启动多个线程

    千次阅读 2017-12-11 12:07:45
    本来一个定时任务在一定时间下只会创建一个线程去执行, 但服务器上的项目却创建了4个线程去执行,导致数据重复创建。
  • 线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。  建议多线程-任务调度,使用如下方式: 首先...
  • 多线程任务处理器改进

    万次阅读 2020-04-03 22:14:00
    多线程改进1、问题介绍2、框架修改工作任务处理类工作任务信息类工作任务线程池类清理任务类3、总结: 1、问题介绍 在上一版本 的多线程处理PDF下载任务的过程中我们用到了多线程工作处理器。不知道读者有没有发现...
  • Java中有多个线程在执行任务,这时候关闭Tomcat,线程任务会立即结束么?在这种情况下,自己创建的线程和线程池会有所区别么?
  • 线程、进程、多线程进程 和 多任务 小结

    千次阅读 多人点赞 2019-04-20 11:59:56
    目录 1 进程 2 线程 3 进程 4 多线程 5 线程与进程的关系 ...6 线程和进程的区别 ...8 线程的优缺点 ...8.1 线程的优点 ...8.2 线程的缺点 ...9 多线程的优缺点 ...9.1 多线程的优点 ...9.2 多线程的缺点 ...8 多任务(进...
  • Linux系统编程——多线程实现多任务

    万次阅读 2015-06-10 18:00:27
    每个进程都拥有自己的数据段、代码段和堆栈段,这就造成进程在进行创建、切换...为了让进程完成一定的工作,进程必须至少包含一个线程线程存在于进程中,共享进程的资源。更详情,请看《进程和线程的区别与联系》。
  • 在python程序中,我们往往会遇到需要在一个脚本里面,同时执行任务的需求,那么此时,我们可以开启一个线程去执行。 如下面,我需要开启一个读取redis白名单线程任务。 每一分钟跟新一次用户白名单。 import ...
  • python多任务——线程

    千次阅读 2019-06-27 11:35:01
    并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已) 并行:指的是任务数小于等于cpu核数...
  • C语言多任务进程,多线程

    千次阅读 2018-04-03 15:44:08
    Linux下多任务机制的介绍多任务处理是指用户在同一时间内运行多个应用程序,每个应用程序被称做一个任务。Linux就是一个支持多任务的操作系统,它比单任务系统的功能增强了许多。当多任务操作系统使用某种任务调度...
  • 多线程异步任务处理

    千次阅读 2018-11-07 21:29:31
    @(多线程&amp;amp;amp;amp;&amp;amp;amp;amp;...多线程异步任务处理 ...文章目录多线程异步任务处理线程池线程池的优缺点常用的线程池技术@Async注解...  线程池是指在初始化一个多线程应用程序过程中创建一个...
  • 多个线程调用同一个线程函数

    千次阅读 2012-03-08 20:15:53
    多个线程调用同一个线程函数 悬赏分:50 - 解决时间:2007-12-11 13:59 如题,能这样吗?因为有很多个操作,但是这些操作都是一样的,所以想用相同的线程函数,但是感觉运行时线程还是一个一个运行,并没有...
  • 多线程之Task(任务

    万次阅读 多人点赞 2018-11-12 15:44:30
    任务和线程的区别: 1、任务是架构在线程之上的,也就是说任务最终...2、任务跟线程不是的关系,比如开10个任务并不是说会开10个线程,这一点任务有点类似线程池,但是任务相比线程池有很小的开销和精确的控制。
  • Springboot - 多线程执行定时任务

    千次阅读 2019-08-31 21:12:08
    文章目录Springboot - 多线程执行定时任务1、创建一个springboot 应用2、配置线程池3、配置定时任务4、定义定时任务异步多线程执行 Springboot - 多线程执行定时任务 1、创建一个springboot 应用 <?xml version=...
  • Java多线程之运行多个任务并处理所有结果

    万次阅读 热门讨论 2018-08-23 23:13:47
    执行器框架给我们提供了一个方法,让我们可以发送给执行器一个任务列表,并等待任务列表中的所有任务执行完毕。然后它将返回一个与任务列表对应的Future列表。 package com.primer.demo.util; import lombok....
  • 一个线程将数据填入对列中,另外几个线程取对列中的数据,对于具体执行的方法,如果有返回值使用Function(没有用到,所以未实现),没有返回值用Consumer,这样通过一行代码就可以实现了。 应用场景, 1.for...
  • SpringBoot多线程任务处理

    千次阅读 2019-03-01 08:56:47
    看到这标题,相信不少人会感到疑惑,回忆你们自己的场景会发现,在Spring的项目中很少有使用多线程处理任务的,没错,大多数时候我们都是使用Spring MVC开发的web项目,默认的Controller,Service,Dao组件的作用...
  • JAVA实现多线程任务执行框架

    千次阅读 2019-07-18 16:31:11
    很长时间没有写过文章了,因现在从事的JAVA方向的系统开发,所以独自写了一个基础的任务执行框架,目的是根据所需应用场景,定制... 第一个线程是每隔10s查询数据库里是否有待执行的任务,如果有加入到任务队列中,...
  • 刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务。打一下基础吧本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的效果 pthread_mutex_t 作为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 632,873
精华内容 253,149
关键字:

一个线程多个任务