线程池

创建线程的方式:
    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()){
}
原文地址:https://www.cnblogs.com/liulong99/p/11885555.html