zoukankan      html  css  js  c++  java
  • Java中线程池的抛出策略、阻塞队列、内存溢出

       Java中官方推荐的线程池有四种:线程池介绍参考:https://www.cnblogs.com/CarpenterLee/p/9558026.html;在jdk1.8加入了 ForkJoinPool的扩展,newWorkStrealingPool,能够合理的使用CPU对任务进行并行操作,适合用于耗时的操作

       但是这几种线程池会造成OOM的问题;

            1、阻塞队列是无界的,导致不停的往队列中加任务,最后导致溢出;

           2、启用的线程数量 过多,例如newCachedThreadPool ,这种线程池的maxmumPoolSize是max_Integer 所以如果当前线程数大于core并且队列已满的情况下,就会创建新线程,如果aliveTime时间较长没有及时GC掉,最终导致溢出;

           

       所以一般推荐使用  new ThreadPoolExecutor(int corePoolSize,int maxNumPoolSize,long keepAliveTime,TimeUnit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler policy)来进行自定义线程池;在这里先重点梳理一下线程池中的阻塞队列和拒绝策略:

     阻塞队列有:

          基于数组结构的: ArrayBlockingQueue  :创建时要指定一个容量;

         基于链表结构的:  LinkedBlockingQueue、LinkedBlockingDeque 创建时可以指定容量,不指定则默认为一个无界队列;newFixedThreadPool、newSingleThreadPool、用的是这个无界的Queue

         同步的: SynchronousQueue:容量为0,这种同步队列只有在有线程写入元素时,另一个线程才能通过poll获取到元素,否则返回null;简单来说这种队列将任务直接提交,而不维持队列,在自定义线程池中默认的队列;newCachedThreadPool用的是这个

         混合的:DelayedWorkQueue:基于DelayQueue和PriorityQueue,是延迟的并且具有自然排序的阻塞队列;newScheduledThreadPool用这个。

                      PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列,对元素没有要求,可以实现Comparable接口也可以提供Comparator来对队列中的元素进行比较,跟时间没有任何关系,仅仅是按照优先级取任务。

    拒绝策略:

    作用场景:在队列已满,并且线程数量达到了maxmumPoolSize的时候;

    拒绝策略的接口是: RejectedExecutionHandler;ThreadPoolExecutor中提供了四个静态方法返回实现了该接口的对象:

        AbortPolicy:抛出RejectedExecutionException异常

        CallerRunsPolicy:直接由提交任务者来执行这个任务(一般是main线程);因此使用这种策略会导致主线程堵塞;容易导致故障

        DiscardOldesPolicy:弹出队列中最年长的任务,尝试将要执行的任务加到队列中;

       DiscardPolicy:忽略这个任务,不抛出异常

            

    附一张很好的线程池工作流程图:

  • 相关阅读:
    转:C++ 智能指针的正确使用方式
    C/C++各个周期的学习
    转: 工作中用的C++库
    转:【软件设计】深入理解日志系统的意义
    初级爬虫第四天
    初级爬虫第三天
    初级爬虫第二天
    初级爬虫第一天
    pep8介绍
    MySQL训练营01
  • 原文地址:https://www.cnblogs.com/zwwang/p/13498022.html
Copyright © 2011-2022 走看看