线程池
创建线程的方式: a、New Thread (代表真正意义的线程) 有自己的生命周期(start) b、Implement Runable 只是重写了run()方法,还是要借助于New Thread() 来创建线程 |
一、使用线程池的目的
(1)减少系统维护线程的开销
(2)解耦、运行和创建分开
(3)线程可以复用
二、线程池的使用
线程池的分类(常用的4类)
方法名 | 解释 |
---|---|
newCachedThreadPool() | 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。 |
newFixedThreadPool(int nThreads) | 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。 |
newSingleThreadExecutor() | 创建一个使用从无界队列运行的单个工作线程的执行程序 |
newScheduledThreadPool(int corePoolSize) | 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。 |
三、线程池的原理
(1)核心参数 —–》ThreadPoolExecutor
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
(a)打开ThreadPoolExecutor源码
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue){
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
其中
参数名 | 解释 |
---|---|
int corePoolSize | 限定线程池的基本大小 |
int maximumPoolSize | 最大线程数量 |
long keepAliveTime | 线程保持的活动时间 |
TimeUnit unit | 线程保持的活动时间单位 |
BlockingQueue workQueue | 任务阻塞队列 |
defaultHandler | 拒绝策略 |
(2)状态变化
(a)ThreadPoolExecutor源码
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
COUNT_BITS :一共29位,表示线程数量,剩下高3位表示状态码
CAPACITY :最大线程数 即2^29,共536870911
(b)线程池的状态
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
(c)线程池的状态转换图
(3)线程池的执行
(a)Execute方法 源码
int c = ctl.get();//拿到当前线程的状态值(高3位)
if (workerCountOf(c) < corePoolSize) {//当线程总数量<核心线程池大小,就会直接处理任务
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
(4)线程池的关闭
pool.shutdown()或者pool.shutdownNow()之后执行
while(!isTerminated()){
}