java 线程池笔记

1、线程池的工具类Executors,通过该工具类可以得到4中线程池对象,即:Executors.newCachedThreadPool()、Executors.newSingleThreadExecutor()、Executors.newFixedThreadPool(nThreads)、Executors.newScheduledThreadPool(corePoolSize)。这些线程的创建都是通过调用ThreadPoolExecutor的构造方法,然后传入不同的参数来实现的。

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {

}

参数说明:

corePoolSize:初始化时给该池子的线程数,无论有无任务需要执行都会启动corePoolSize个线程放在池子;

maximumPoolSize:当任务队列过多时最大能扩展的线程数;

keepAliveTime:当任务执行完了以后,空闲线程最大能空闲的时间,超过该时间则回收。比如corePoolSize为2,maximumPoolSize为4,BlockingQueue队列为2个长度,此时来了10个任务,则前2个任务交给corePoolSize 那两个线程来执行,3、4任务缓存在BlockingQueue队列中,第5个任务到来的时候,就要再起一个线程,第6个任务来了再起一个线程,此时总线程数已经达到了maximumPoolSize,有新任务来了也不能再起新的线程了(后面的7、8、9、10 任务请求再来的话就要根据设置的RejectedExecutionHandler策略来处理,此处先不考虑),当任务执行完后,新启动的两个线程也就空闲下来,这时就开始计时,空闲时间达到了keepAliveTime则把线程回收了,这是就是剩下corePoolSize个线程存活了。

缓冲队列参考:https://blog.csdn.net/ican87/article/details/80874933

workQueue:缓存的队列,有多重实现队列。实现1:ArrayBlockingQueue,有界队列,可以限制缓存队列的大小;实现二:LinkedBlockingQueue,无界队列,能无限缓存队列,理论上可以缓存一直到内存耗尽,使用该队列后则maximumPoolSize就失效了;实现三:SynchronousQueue,直接提交策略表示线程池不对任务进行缓存。新进任务直接提交给线程池,当线程池中没有空闲线程时,创建一个新的线程处理此任务。这种策略需要线程池具有无限增长的可能性。

handler:任务过多(缓存队列已满,并且已扩展到maximumPoolSize个线程,后续再来新的任务就会触发)触发拒绝策略。ThreadPoolExecutor内置了多中静态内部类,对应各种拒绝策略。

(1)AbortPolicy
拒绝策略:抛出运行时异常RejectedExecutionException。
这种策略丢弃任务,并抛出异常。(jdk默认策略)
(2)DiscardPolicy
拒绝策略:不能执行的任务将被丢弃。
这种策略什么都没做。
(3)DiscardOldestPolicy
拒绝策略:如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序。

 2、各种线程池的实现

//缓存池,初始化0个线程,使用SynchronousQueue队列每次来了新任务马上起一个新的线程,而不是缓存下来,最大可以起Integer.MAX_VALUE个线程(内存够用前提下) 
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
//固定线程数的线程池,注意他的初始化线程数和最大线程数是一样,一旦任务超过线程数就开始无限缓存,等线程处理完其他任务后再从无界队列中取任务来处理 
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
//单个线程池,相当于把固定池的线程数设置成1个 
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
构造方法调用过程如下 

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }

3、线程池中任务执行的流程:

猜你喜欢

转载自www.cnblogs.com/urmagical/p/10547465.html