• 线程池类型场景和问题


    https://mp.weixin.qq.com/s/Cv5gTiz9RORnesoQmyROIw

    Executors线程工厂类
    1、Executors.newCachedThreadPool();
    说明:

       创建的线程池核心线程0 , 最大线程是Integer.MaxValue。 线程空闲存活时间1分钟。 默认异常拒绝策略,使用SynchronousQueue队

    特点:

      每次添加任务如果没有空闲线程就会新建一个线程去执行。
      SynchronousQueue是阻塞队列,加入任务的线程会阻塞住,直到其它线程从中取走任务才会结束阻塞
      线程创建上限近乎无限

    队列:

      SynchronousQueue

    适用场景:

      所以它适用于任务加入比较稳当且加入间隔短的场景

    实现:

      new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue());

    问题:

      可能在大量请求的时候,创建了过多的线程,导致的效率低下,甚至OOM。

    2、Executors.newFixedThreadPool(int);
    说明: 

      核心线程和最大线程数是你传入的参数。 其他参数和 Executors.newSingleThreadExecutor一样

    实现:

      new ThreadPoolExecutor(nThreads, nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue());

    阻塞队列

      无界的 LinkedBlockingQueue 阻塞队列

    问题:

      也是有可能造成队列积压,以至于导致OOM的问题,所以,我们在使用时要合理的设置线程数。

      newFixedThreadPool线程池的核心线程数是固定的,它使用了近乎于无界的 LinkedBlockingQueue 阻塞队列。(平安问过

      当核心线程用完后,任务会入队到阻塞队列,如果任务执行的时间比较长,没有释放,会导致越来越多的任务堆积到阻塞队列,最后导致机器的内存使用不停的飙升,造成JVM OOM。

    (参考: https://www.cnblogs.com/hulianwangjiagoushi/p/11498353.html)

    3、Executors.newSingleThreadExecutor();
    说明:

      创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照顺序执行。

    特点:

      只有一个线程

      近乎可以接收无限任务的队列, 可以堆积大量任务

      适用于任务持续加入但是任务数并不多的场景

    实现:

      new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue())

    问题:

      如果有其他请求任务时,此时线程没有空闲,就会将此任务放到队列中等待执行。

      主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
     

    4、Executors.newScheduledThreadPool(int);
    说明:

      创建一个定长线程池,支持定时及周期性任务执行。

    特点:

      核心线程是传入的参数,最大线程是int上线, 默认存活时间是10毫秒, 任务队列使用自己实现的DelayedWorkQueue, 拒绝策略异常策略

      加入任务的时候,会把任务和定时时间构建一个RunnableScheduledFuture对象,再把这个对象放入DelayedWorkQueue队列中,

      DelayedWorkQueue是一个有序队列, 他会根据内部的RunnableScheduledFuture的运行时间排序内部对象。

      任务加入后就会启动一个线程。 这个线程会从DelayedWorkQueue中获取一个任务。

    阻塞队列:

      DelayedWorkQueue内部是按照时间从前完后获取任务的。如果任务的中的时间还没有到。 获取的就是null。

       获取任务结束,线程会休眠10毫秒。所以这个定时任务的执行最小间隔是10毫秒的。

    内部实现

      new ScheduledThreadPoolExecutor(corePoolSize)

    问题:

      主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

  • 相关阅读:
    【JDK】JDK源码分析-LinkedList
    【JDK】JDK源码-Queue, Deque
    【JDK】JDK源码分析-Vector
    【JDK】JDK源码分析-ArrayList
    Jmeter-安装及配置(一)
    数据库连接池技术
    2017年度总结
    Windows重装系统
    Java + Selenium + Appium手机自动化测试
    DbVisualizer出现下列错误:Could not read XML file
  • 原文地址:https://www.cnblogs.com/Jomini/p/15380602.html
Copyright © 2020-2023  润新知