线程池

来源:互联网 发布:淘宝售后主管岗位职责 编辑:程序博客网 时间:2024/06/03 17:00
  • 线程池的好处:
  1. 降低资源消耗:避免了频繁创建和销毁线程的资源消耗;
  2. 提高相应速度:当有新的任务到达时,不必每次都新建线程就可以立即执行;
  3. 提高线程的可管理性:线程池对线程进行统一分配、调优和监控。不允许无限制的创建线程。

  • 线程池源码分析其实现原理
当线程池接收到一个新的提交任务,线程池如何处理这个新任务,这部分主要学习线程池的针对新任务的处理流程。

  1. 当前运行的线程数小于corePoolSize,创建新线程来执行任务,该步骤需要获取全局锁;
  2. 运行的线程数等于或大于corePoolSize,则将任务加入到BlockingQueue;
  3. 如果BlockingQueue已满,则无法加入,创建新的线程来处理任务;
  4. 如果新建线程使当前运行的线程超出maxiumPoolSize,该任务采取相应测策略进行处理;

  • 线程池的创建
采用ThreadPoolExecutor创建线程池:

上述几个关键参数的解析:
corePoolSize:可以理解为核心线程池大小,线程池通常会提前创建并启动基本线程,当线程数量小于corePoolSize时,提交新任务就会创建一个线程,即使线程池中其他线程是空闲的;
maximumPoolSize:线程池允许创建的最大线程数量,这就是线程数量的上界,不能再多了。新到任务时,如果当前线程池中的线程数量大于corePoolSize并小于maximumPoolSize会将该任务加入到任务队列中等待执行,如果任务队列无限大,那么该maximumPoolSize参数没有实际意义。
keepAliveTime:池中线程工作空闲后,保持存活的时间。针对任务多且执行时间短的情况可以增大时间。提升线程池效率。
timeUnit:线程活动保持时间的单位,DAYS、HOURS、MINUTES等。
blockingQueue:任务队列,用于保存等待执行的任务的阻塞队列,有以下几种阻塞队列:
  • ArrayBlockingQueue:基于数组,FIFO先进先出原则;
  • LinkedBlockingQueue:基于链表,FIFO先进先出原则,吞吐量高;
  • SynchronousQueue:每一插入操作必须等待另一个移除操作完成才可以,否则该插入操作处于阻塞状态,吞吐量高于LinkedBlockingQueue;
  • PriorityBlockingQueue:具有优先级的无线阻塞队列;
threadFactory:线程工厂,为每个创建出来的线程设置更有意义的名字;
rejectedExecutionHandler:当任务队列满时,说明线程池也处于饱和状态,必须采用一种拒绝策略来处理新提交的任务。通常的策略方式如下:
    • AbortPolicy:直接抛出异常,默认就是这种策略;
    • CallerRunsPolicy:只有调用者所在线程运行任务;
    • DiscardOldestPolicy:丢弃队列里最近的一个任务并执行当前任务;
    • DiscardPolicy:不处理,丢弃掉;
也可以通过实现RejectedExecutionHandler接口自定义策略

  • 向线程池提交任务
可以使用execute()和submit()两个方法向线程池提交任务;
  • 关闭线程池
调用线程池通过调用线程池的shutdown和shutdownNow方法。原理是遍历线程池中的工作线程,逐个调用interrupt方法进行中断。shutdown方法将线程池的状态设置为SHUTDOWN,然后中断没有正在执行的任务线程;shutdownNow将线程池设置为STOP,尝试中断所有的线程。