线程池详解

什么是线程池

线程池的状态

线程池ThreadPoolExector 中有个院子变量:

高三位存储的是线程的状态,其他位存储线程数量
AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING,0))
//29位  int的位数 减三
int COUNT_BITS = Integer.SIZE - 3;
// 2^29-1  大约5亿1
int CAPACITY   = (1 << COUNT_BITS) - 1;

// Packing and unpacking ctl  打包和解包ctl
int runStateOf(int c)     { return c & ~CAPACITY; }
int workerCountOf(int c)  { return c & CAPACITY; }
// 线程运行状态 和 线程数 返回ctl的值
int ctlOf(int rs, int wc) { return rs | wc; }

线程池状态流转图五种状态

    // runState is stored in the high-order bits 从小到大排列
    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;

线程池的四种拒绝策略

这四个策略均实现了接口:RejectedExecutionHandler
通过 void rejectedExecution(Runnable r, ThreadPoolExecutor executor);方法来处理超出容量的线程。
在这里插入图片描述默认的拒绝策略:

  private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

线程池的创建方式

ThreadPoolExector源码解析

类结构

在这里插入图片描述ExecutorService 和Executor 都是接口只是定义了方法具体的实现在AbstractExecutorService 和 ThreadPoolExecutor中

简介

ThreadPoolExecutor 主体由两部分组成:

  1. 组成线程池的任务集合
// 用来保证workers 的安全,shutdown 和 shutdownNow时也用的到
private final ReentrantLock mainLock = new ReentrantLock();
//Set containing all worker threads in pool. Accessed only when holding mainLock. 
//包含池中所有工作线程的集合,仅在持有mainLock时访问。
private final HashSet<Worker> workers = new HashSet<Worker>();
  1. 保存任务的队列
//用于保存任务和移交给工作线程的队列
private final BlockingQueue<Runnable> workQueue;

Worker 介绍

worker 类结构

在这里插入图片描述Worker 是ThreadPoolExecutor的内部类。
worker实现了Runnable接口,自己本身就是一个线程。
worker继承了AbstractQueuedSynchronizer 同步器

worker中的变量

/** Thread this worker is running in.  Null if factory fails. */
//运行任务的线程
final Thread thread;
 /** Initial task to run.  Possibly null. */
 //正式运行的任务,可能为null
Runnable firstTask;
/** Per-thread task counter */
//线程的任务计数器
volatile long completedTasks;
构造方法
Worker(Runnable firstTask) {
  setState(-1); // inhibit interrupts until runWorker
  this.firstTask = firstTask;
  this.thread = getThreadFactory().newThread(this);
}

由构造方法可以看出thread就是当前的worker。

run方法
public void run() {
    runWorker(this);
}

run方法调用了外部的ThreadPoolExecutor的 runWorker方法

    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        //用来标识,完成任务前有没有被终止
        boolean completedAbruptly = true;
        try {
            //在task=null时,会通过getTask()方法从线程池中获取task 
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    //预留方法
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        // 调用任务的run方法
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                       // 预留方法
                        afterExecute(task, thrown);
                    }
                } finally {
                	//任务执行完成,清空工人的任务
                    task = null;
                    // 为当前工人的任务数+1
                    w.completedTasks++;
                    w.unlock();
                }
            }
            //完成任务前没有被终止
            completedAbruptly = false;
        } finally {
        	//回收工人的方法
            processWorkerExit(w, completedAbruptly);
        }
    }
processWorkerExit 回收工人的方法
/**
清理垂死的工人,并进行登记。仅从工作线程调用。
w: 工人
completedAbruptly: 工人是否因为用户异常而死亡
**/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
        // 如果因为用户异常导致线程退出 则任务数量减一
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
        	//将工人完成的任务数给总任务数
            completedTaskCount += w.completedTasks;
            //将工人从工人集合中移除
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        // 线程池为运行状态 或 shutdown状态
        if (runStateLessThan(c, STOP)) {
            //不是用户异常导致的工人死亡
            if (!completedAbruptly) {
            	//如果允许核心线程长期存活   min= corPoolSize 否则为0
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //不允许核心线程长期存活,且 队列为空 则 min = 1
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                 // 工人数量 >= min 不用创建工人
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            // 如果是用户异常导致的退出 新建线程
            // 如果工人正产死亡,且人工数量小于核心线程数 新建工人
            addWorker(null, false);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值