JAVA并发 线程池

线程池的优势

  1. 减少资源的开销:减少了每次创建线程和销毁线程的开销。
  2. 提高响应速度:每次请求到来时,由于线程已经创建完成,可以直接执行任务,提高了响应速度。
  3. 提高线程的可管理性:线程是一种稀缺资源,如果不进行管理,会造成很大的资源浪费,而且还会影响系统的稳定性。线程池对线程的创建、停止、数量等因素控制,保证线程正常运行的同时,还方便性能的调优。

线程池的实现原理

线程池由:工作线程队列和,阻塞队列构成。

工作队列:指一组已经处在运行中的队列,他们不断的在阻塞队列中领取任务。

阻塞队列:是用来存储来不及处理的任务。

创建线程池方法详解

new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,timeUnit,runableTaskQueue,Handler);
  • corePoolSize:基本线程数量;表示线程池中运行的线程的数量值在这个上下波动。
  • maximumPoolSize:最大线程数;这个是线程的上限,如果实际线程数量达到这个值并且阻塞队列未满,任务放在阻塞队列中,否则,阻塞队列已满,调用饱和策略。
  • keeyAliveTime:线程空闲的最大时间,timeUnit是这个单位。
  • runableTaskQueue:任务队列(阻塞队列);这是一个阻塞队列,通常有如下几种。
    1. ArrayBlockingQueue:是由数组实现的阻塞队列,是FIFO的原则。
    2. LinkedBlockingQueue:是由一个链表实现的阻塞队列,也是FIFO原则,在newFixedThreadPool使用的阻塞队列。他的吞吐量比ArrayBlockingQueue高,是一个无边界队列。
    3. SynchronousQueue:是一个没有任何存储空间的阻塞队列,任务提交给他们后必须交给一条线程处理,如果当前没有空闲线程,则立即创建一个新的工作线程。cacheThreadPool使用的阻塞队列就是他。
    4. PriorityBlockingQueue:他是一个优先权阻塞队列。
  • handler:饱和策略;当实际线程数达到maximumPoolSize,并且阻塞队列已满时,就会调用饱和策略。有:AbortPolicy:默认直接抛异常;CallerRunPolicy:只调用者所在的线程执行任务。DiscardOlderPolicy:丢弃队列中最持久的任务。DiscardPolicy:丢弃当前任务。

提交任务

两种任务的提交方式:Runable,Callable;

Runable:没有返回值,只执行,并且在执行过程中不会抛出异常,通过execute提交。

Callable:有返回值,是Future类型,可以抛出异常,通过函数submit提交,可以通过get获取元素值。

关闭线程池

关闭线程池的方式有shutDown和shutDownNow,关闭时,会遍历所有的线程调用他们的interrupt函数进行关闭。

shutDown:只关闭阻塞队列中的线程,对已经正在执行的线程会让他们正常结束。

shutDownNow:他会关闭全部的线程,不管是阻塞队列的还是正在运行的,都会全部关闭掉。

ThreadPoolExecutor运行机制

请求来临时:①.当前的实际线程小于corePoolSzie,即使有空闲线程,也会创建一个新的工作线程;

      ②.若当前的实际线程在corePoolSize和maximumPoolSize之间,并且阻塞队列没有满,那么将任务之间放在阻塞队列中。

      ③.若当实际线程数量小于maximumPoolSize,但阻塞线程已经满了,则直接创建新线程处理任务。

      ④.若当实际线程数量已经达到maximumPoolSize并且阻塞队列已经满了,调用饱和策略。

设置线程池的大小

任务分为:CPU密集型(较小的线程池,核心数+1 )、IO密集型(较大的线程池,2*CPU核心数)、混合型 (将任务分成IO密集型和CPU密集型任务,,然后分别用不同的线程池去处理).

 

posted @ 2018-09-23 10:58  轻抚丶两袖风尘  阅读(195)  评论(0编辑  收藏  举报