浅析多线程及用法(实例)

来源:互联网 发布:少数民族人脸数据库 编辑:程序博客网 时间:2024/06/07 04:54
    在探讨多线程之前,我们先来看看下面几个问题   
   首先认识下多线程是个什么?
       在我理解,多线程就是多个指令流,并发执行,线程之间没有相互依赖关系,没有先后顺序。
    多线程的作用是用来干什么的?
       多线程应用程序将程序划分为多个独立的任务,多线程主要是对程序的响应速度,运行的效率会有质的飞越。
    多线程一定能够提高效率吗?
        上面提到过,多线能够提高程序的响应速度和效率,其实不是所有场景多线程都能提高程序的响应速度和效率的,假设有两个场景:
        1,现在一张桌子上有两个苹果,一个人去拿,和两个人去哪,两种情况,那种情况先拿到苹果,两个人去拿苹果一定快吗?答案是不一定。
        2,现在有一个注满水的水塘,现在需要把池塘的水抽干,现在问题来了,用一个抽水机快 还是用10个抽水机速度快,答案显而易见,当然是10个抽水机快。
        
       多线程是一个复杂的东西,多线程并不一定能提供程序的运行的效率,多线程有自己的应用场景,当我们的程序需要处理一个繁杂的任务的时候,耗时很长,而这个任务,并不具备原子性,
     能够将任务拆分成多个线程来执行。
       但是运用多线程技术的时候,需要考虑到的问题,多线程会占用cpu和内存资源,如果线程多了,cpu负担太大,多线程在访问公共资源的时候,很有可能会出现后一个线程覆盖前一个
     线程的公共资源的内容。
        现在和大家分享一种多线程的应用场景和具体实现。
          我本人是从事互联网电商行业,现在分享一下我工作中对多线程的应用,在电商行业中,会存在这样一种用户场景,现在有2000个商品信息用excel保存,需要把这2000个商品入库,在入库
     的途中,还会生成促销价等一些列的操作,如果用单线程的话,处理的速度会非常的缓慢。这个时候多线程就体现出它的优势了。
    
     在这之前,我们先来看一个东西,现在有一个 ArrayList<Product> 这个ArrayList里面 放了2000个Product对象,假设现在我需要用多线程让这2000个商品入库,这么处理?
      首先我们知道,List 对象里面是可以存放任意类型的对象,我们可以把装有2000个Product对象的ArrayList 拆分成20个list,每个一个list中则存放100个商品。数据格式大概
      这样子的List<List<...>,List<....>,List<....>>,一个大的List集合中存放若干个小的List 集合,每一个线程来处理一个小的list。
      
     再来认识几个东西:
     Executors:创建线程和管理线程的类,Executors.newFixedThreadPool(ing arg) 此方法是用来创建一个线程池,参数表示创建线程池中线程的个数。
     method:execute(),用来执行任务
     CountDownLatch:线程的辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
     method: countDown(),当前线程调用此方法,则计数减一
             awaint(),调用此方法会一直阻塞当前线程,直到计时器的值为0
            
     了解了以上之后,直接上代码:
    
     public List<E> startTreadsProudce(List<T> activityIdList, Integer eachPageSize){
        //此方法把activityIdList 调用subList方法(方法如下),切割成如果个小的list 放入totalList中
        List<List<T>> totalList = (List<List<T>>)subList(activityIdList, eachPageSize, totalPageCount);
        //用来接收每个线程处理返回的返回值
        final List<E> resultList = new CopyOnWriteArrayList<E>();
        //辅助类,用来计数和线程没执行完处于等待状态
        final CountDownLatch countDownLatch = new CountDownLatch(totalList.size());
        //创建线程池,线程池的个数为 切割后的list总数
        final ExecutorService executorService = Executors.newFixedThreadPool(totalList.size());
        //多线程开始
        for (final List<T> list : totalList) {
            Runnable run = new Runnable() {
                public void run() {
                    try {
                        //处理入库操作
                        List<E> itemList = produce(list);
                        resultList.addAll(itemList);
                    } catch (Exception ex) {
                        logger.error("BaseCurrentThreadsManager.startCurrentTreadsProudce() error: ", ex);
                    } finally {
                        //当线程执行完,计数减一
                        countDownLatch.countDown();
                    }
                }
            };
            //线程执行
            executorService.submit(run);
        }
        try {
         //如果线程没有执行完,则一直处于等待状态
            countDownLatch.await();
        } catch (InterruptedException e) {
            logger.error("BaseCurrentThreadsManager.startCurrentTreadsProudce() --> countDownLatch.await() error: " , e);
        }finally{
            //执行完后关闭线程
            executorService.shutdown();
        }
        return resultList;
    }
            
    public static <T> List<List<T>> subList(List<T> list, Integer eachPageSize, Integer totalPageCount){
        List<List<T>> returnBatchList = new ArrayList<List<T>>();
        if(CollectionUtils.isNotEmpty(list)){
            int nextPageCount = 0;
            int prePageCount = 0;
            int totalPageNum = (list.size() + eachPageSize - 1)/ eachPageSize;
        
                //actually pageNumber is totalPageNum
                for (int pageCount = 1 ; pageCount <= totalPageNum ; pageCount++) {
                    prePageCount = (pageCount - 1) * eachPageSize;
                    if(pageCount == totalPageNum){
                        nextPageCount = list.size();
                    }else{
                        nextPageCount = pageCount * eachPageSize;
                    }
                    returnBatchList.add(list.subList(prePageCount , nextPageCount));
                }
            
        }
        return returnBatchList;
    }          
    
                                                                                                                                                                               以上均是自己总结,如有错误,请欢迎批评指正。谢谢!
          

0 0
原创粉丝点击