• 线程池


    Java常见的创建线程(线程池)有三个:

    Executors.newCachedThreadPool();

    Executors.newFixedThreadPool(10);

    Executors.newSingleThreadExecutor();

    查源码,都是new 的一个线程池类 ThreadPoolExecutor,只是参数不同;

    ThreadPoolExecutor

    参数

    ThreadPoolExecutor 的参数有6个:

    corePoolSize 、 maximumPoolSize 、 keepAliveTime 、 workQueue

    threadFactory 、 handler ;

    非核心参数:

    • ThreadFactory threadFactory,制造线程的工厂

    • RejectedExecutionHandler handler,线程超过线程池的最大处理量时,抛出拒绝执行异常

    核心参数

    • corePoolSize,一直存活的核心线程数,

    • maximumPoolSize,最大线程数,线程池最大容量

    • keepAliveTime,超过corePoolSize数量的空闲线程可存活时间,超过这个时间的线程对象会被销毁

    • workQueue,一个阻塞队列,用例存放任务,等待线程执行

    线程池执行流程

    假设现在有如下一个线程池

    线程任务执行流程如下:

    • 先来的任务 T1 ... T10 会直接被 core thread 的 ct1 ... ct10 执行

    • 继续来的任务 T11 ... T20 会被放进 work queue中,因为队列的size=10,就刚好存放 10个任务( core thread 的 ct1 ... ct10 还在执行 T1 ... T10)

    • 继续来的任务 T21 ... T30 ,线程池会创建其他线程对象 other thread(最多10个,因为线程池的最大线程数为20)的 ot1 ... ot10 来执行

    • 如果仍有任务进来 T31... ,此时会报异常,线程池已经不能再执行和保存任务了,后续来的任务都不会执行(RejectedExecutionHandler 处理),因为线程池的最大容量= maximumPoolSize + workQueue = 30

    • 如果有任务执行完成(ct1 ... ct10执行的 T1 ...T10,ot1 ... ot10执行的 T21 ... T31),空闲的线程就会去执行 workQueue中的任务

    • 如果workQueue中的任务也执行完成, 没有其他任务进来,空闲的线程存活 10S(keepAliveTime)后会被销毁(core thread 和 other thread 都有可能被销毁),直到线程池中存活的线程=10个(corePoolSize)

    Executors 的三个线程池

    newCachedThreadPool()

    public static ExecutorService newCachedThreadPool() {
           return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                         60L, TimeUnit.SECONDS,
                                         new SynchronousQueue<Runnable>());
      }

    源码可见

    • 核心线程数是 0

    • 最大线程数是 无穷大

    • 空闲线程存活 60S

    • 阻塞队列 SynchronousQueue,看源码可知,size = 0

    所以 newCachedThreadPool 是一个初始线程数为0,线程数随着任务增加而增加,没有阻塞队列存放任务,空闲线程存活60S的线程池

    newFixedThreadPool()

    public static ExecutorService newFixedThreadPool(int nThreads) {
           return new ThreadPoolExecutor(nThreads, nThreads,
                                         0L, TimeUnit.MILLISECONDS,
                                         new LinkedBlockingQueue<Runnable>());
      }

    源码可见

    • 核心线程数是传入的参数 nThreads

    • 最大线程数是传入的参数 nThreads

    • 空闲线程存活时间是 0s(corePoolSize=maximumPoolSize,也不会有其他线程进入,线程池的线程数一直都是 nThreads)

    • 阻塞列队 LinkedBlockingQueue,是一个链表,size不限

    所以 newFixedThreadPool 是一个 初始线程数和最大线程数都为 nThreads,阻塞队列可存放无限多任务,无需要销毁的空闲线程的线程池

    newSingleThreadExecutor()

        public static ExecutorService newSingleThreadExecutor() {
           return new FinalizableDelegatedExecutorService
              (new ThreadPoolExecutor(1, 1,
                                       0L, TimeUnit.MILLISECONDS,
                                       new LinkedBlockingQueue<Runnable>()));
      }

    newSingleThreadExecutor 就是只有 一个线程的线程池(特殊的newFixedThreadPool )

  • 相关阅读:
    php中的多态
    面向对象的继承与组合
    PHP中的__call和__callStatic方法
    PHP中的__set和__get方法
    PHP中对象的本质
    mysql字符串查找(统计客源)
    linux查看文件大小
    mysql常用字符串操作函数大全,以及实例
    mysql滑动订单问题
    mysql列反转Pivoting
  • 原文地址:https://www.cnblogs.com/yjh1995/p/15902743.html
Copyright © 2020-2023  润新知