
一.Java线程池的介绍
使用线程池的好处
(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
(2)提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。

(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控
源码分析,一共定义了四个构造器,前三个构造器最终都调用了第四个构造器进行初始化
public class ThreadPoolExecutor extends AbstractExecutorService {
.....
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
...
}
构造器里面参数的解释

corePollSize:核心线程数。在创建了线程池后,线程中没有任何线程java面试题及答案,等到有任务到来时才创建线程去执行任务。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
maximumPoolSize:线程池所能容纳的最大线程数。当活动线程(核心线程+非核心线程)达到这个数值后,后续任务将会根据 RejectedExecutionHandler 来进行拒绝策略处理。
keepAliveTime:空闲的线程保留的时间。
TimeUnit:空闲线程的保留时间单位。

TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
BlockingQueue<Runnable>:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选。
ThreadFactory:线程工厂,用来创建线程
如果使用的是有界队列比如arrayblockingqueue,任务首先会被添加到arrayblockingqueue中,arrayblockingqueue满了,会根据maximumpoolsize的值增加线程数量,如果增加了线程数量还是处理不过来,arrayblockingqueue继续满,那么则会使用拒绝策略rejectedexecutionhandler处理满了的任务java面试题及答案,默认是abortpolicy。如果任务offer到队列失败(offer是个同步方法,和add一样,只是不抛出异常),即队列已满且线程个数小于maxpoolsize,则尝试创建新的线程执行此任务。 /*互斥量和递归互斥量要在同一个任务中获取和释放,递归互斥量可以在一个任务中多次获取,当第一次获取递归互斥量时,队列结构体成员指针pxmutexholder指向获取递归互斥量的任务tcb,在此获取这个递归互斥量时,如果这个指针指向的tcb和当前任务tcb相同,只需要将递归次数计数器u.uxrecursivecallcount加1即可,不需要再操作队列.*/。
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
线程池工作原则:
1、当线程池中线程数量小于 corePoolSize 则创建线程,并处理请求。
2、如果线程池中的线程数量大于等于corepoolsize,但缓冲队列workqueue未满,则将新添加的任务放到workqueue中,按照fifo的原则依次等待执行(线程池中有线程空闲出来后依次将缓冲队列中的任务交付给空闲的线程执行)。如果线程池中的线程数量已经达到或者超过核心线程的数量, 那么任务会被插入到任务队列中排队等待执行.。通过executor#newfixedthreadpool()方法来创建. 它是一种线程数量固定的线程池, 当线程处于空闲状态时, 它们并不会被回收, 除非线程池关闭了. 当所有的线程都处于活动状态时, 新任务都会处于等待状态, 直到有线程空闲出来. 由于fixedthreadpool只有核心线程并且这些核心线程不会被回收, 这意味着它能够更加快速地响应外界的请求.。
3、当 taskQueue 已存满,放不下新任务时则新建非核心线程入池,并处理请求直到线程数目达到 maximumPoolSize(最大线程数量设置值)。
3、如果线程池中的线程数量大于等于corepoolsize,且缓冲队列workqueue已满,但线程池中的线程数量小于maximumpoolsize,则会创建新的线程来处理被添加的任务。当线程数小于核心线程数时,即使现有的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。任务队列是 synchronousqueue 这个队列的特点是,它并不能放置任何任务在其队列中,当有任务被提交时,使用synchronousqueue的线程池会立即为该任务创建一个线程(如果线程数量没有达到最大时,如果达到了最大,那么该任务会被拒绝)。
参考博客地址:https://blog.csdn.net/maoruibin9035/article/details/71425379
https://blog.csdn.net/angelasan/article/details/44917283。转载自:https://blog.csdn.net/javazejian/article/details/51932554。转载自:https://blog.csdn.net/a19881029/article/details/26348627。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-115502-1.html