【JAVA】线程--线程池

2.线程池(juc包下)-面试重点

1)使用线程池的优点如下:

(1)降低资源的消耗:通过重复利用已创建的线程降低线程创建与销毁带来的消耗。                                                  (2)提高响应的速度:当新任务到达时,任务不需要等待线程创建就可以立即执行。                                                  (3)提高线程的可管理性:使用线程池可以统一执行线程的分配、调度与监控。


图:
  corePoolSize->BlockingQueue->maxiumSize->RejectedExecutionHandler  

 2)线程池执行任务的流程:当一个Runnable/Callable对象到达线程池时,执行策略如下:

 第一步:首先判断核心线程池中的线程是否都在执行任务,如果是,再次查看核心线程池是否已满,如果未满创建新的线 程执行任务
如果核心线程池有空闲线程,则任务直接分配给空闲线程执行,否则执行第二步。
第二步:判断工作队列(BlockQueue)是否已满,如果工作队列没有满,将提交任务存储到工作队列中等待核心池调 度,否则,若工作队列已满,进入步骤3 第三步:判断当前线程池中的线程数是否已达到最大值maxumSize,若已达到最大值,将任务交给饱和策略处理,否 则,继续创建新线程执行此任务。

3)线程池的使用 通过创建ThreadPoolExecutor来创建线程池  

public ThreadPoolExecutor(int corePoolSize,                            
                          int maximumPoolSize,                            
                          long keepAliveTime,                                    
                          TimeUnit unit,                                            
                          BlockingQueue workQueue,                               
                          RejectedExecutionHandler handler)


(1)corePoolSize(核心池大小):当提交任务到线程池时,线程池会创建一个新的线程来执行任务,即使核心池中有 其他空闲线程也会创建新线程,一直到线程数达到核心池的大小为止。
调用prestartAllCoreThread()线程池会提前创建并启动所有核心线程。

(2)workQueue(工作队列):用于保存等待执行任务的阻塞队列。可以选择以下几个直阻塞队列:                                               a. ArrayBlockingQueue:基于数组结构的有界阻塞队列,此队列按照FIFO原则对元素进行排序。
   b. LinkedBlockingQueue:基于链表结构的阻塞队列,按照FIFO对元素进行排序,吞吐量高于 ArrayBlockingQueue,Executors.newFixedThreadPool()采用此队列
  c. SynchronousQueue:一个不存储元素的阻塞队列,无界队列。每个插入操作必须等到另一个线程调用移除操 作,否则插入操作一直处于阻塞状态,通常吞吐量比LinkedBlockingQueue还要高。 Executors.newCachedThreadPool()采用此队列
  d. PriorityBlockingQueue:具有优先级的无界阻塞队列。 (3)maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。如果队列已满并且已创建的线程数小于 此参数,则线程池会再创建新的线程执行任务。否则,调用饱和策略处理。如果采用无界队列,次参数无意义。
(4)keepAliveTime(线程活动保持时间):线程池的工作线程空间后,保持存活的时间。若任务很多,并且每个任务 执行的时间很短,可以调大此参数来提高线程利用率。
(5)TimeUnit(第四个参数的时间单位)                                                                                                                                               (6)RejectedExecutionHandler(饱和策略):当队列和线程池都满了的情况,说明线程池处于饱和状态,此时使用 饱和策略来处理任务 。 默认采用AbortPolicy.JDK一共内置四种饱和策略 a. AbortPolicy,表示无法处理新任务抛出异常,JDK默认采用此策略 b. CallerRunsPolicy,等待调用者线程空闲后运行任务。 c. DiscardOldestPolicy,丢弃阻塞队列中最近的一个任务并执行当前任务。 d.DiscardPolicy,不处理,直接将新任务丢弃,也不报错   FutureTask类执行任务只执行一次,并且会阻塞其他线程 Future.get()方法会阻塞其他线程,一直等到当前Callable线程执行完毕拿到返回值为止。   JDK7新增Fork-join()框架,将大任务拆分成多个子任务进行,最终将结果由各个子任务汇总得来。  

 4)JDK内置的四大线程池
普通调度池:
(1)创建无大小限制的线程池:Exectors.newCachedThreadPool()
适用于很多短期任务的小程序,负载较轻的服务器。
(2)固定大小线程池:Exectors.newFixedThreadPool(int nThreads)
适用于为了满足资源管理的需求而需要限制当前线程数量的应用场合,适用于负载比较重的服务器
(3)单线程池:Exectors.newSingleThreadPool()
适用于需要保证顺序的执行各个任务,并且在任意时间点不会有多个线程活动的场景。
定时调度池:
 

猜你喜欢

转载自blog.csdn.net/hgelin/article/details/89353501