线程池属性与addWorker方法源码分析

  实际业务中的程序总是会使用多线程,线程池则是多线程资源管理最常用的方式。
  线程池类ThreadPoolExecutor构造方法中有七个参数,具体如下:

  1. int corePoolSize:核心线程数量,默认情况下,即时没有任务,线程池也会维持核心线程不被销毁;
  2. int maximumPoolSize:最大线程数量,当没有空闲线程可用时,线程池会创建新线程来执行任务,线程总数不会超过此属性;
  3. long keepAliveTime:线程空闲时间,超过该时间后,线程池会销毁线程,默认情况下,核心线程不会被销毁;
  4. TimeUnit unit:线程空闲时间的时间单位;
  5. BlockingQueue workQueue:任务缓存队列,当线程数已达最大数量,且没有空闲线程时,新任务会入队等待;
  6. ThreadFactory threadFactory:创建线程使用的线程工厂,其中可以设置线程名称,方便在日志中排查问题;
  7. RejectedExecutionHandler handler:拒绝策略,当任务缓存队列满后,新收到的任务会交由拒绝策略处理。

  需要特别注意的是,最后三个属性应当按照实际业务需求进行实例化,而非使用Executors提供的默认实现。

  阅读类或方法的JavaDoc注释可以快速了解其功能和使用方式,但如果想具体了解其逻辑,学习其中的实现方法,看源码是最好的选择,下面以ThreadPoolExecutor类中的增加新线程的addWorker方法为例做源码分析(Java8):

    private boolean addWorker(Runnable firstTask, boolean core) {
    	//响应continue retry
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            //多种不允许创建新线程的情况
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
            	//不能超过最大线程数
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                //线程总数+1,在线程创建前先检查总数是否合法,减少开销
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                    //compareAndIncrementWorkerCount方法失败后重试
            }
        }

		//开始创建工作线程
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
            	//先持有锁,再创建线程
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        //检查线程是否已经已启动
                        if (t.isAlive())
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        //线程池运行时的最大并发任务数
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                //启动线程
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
        	//增加线程失败,把开始时调用compareAndIncrementWorkerCount增加的值再减掉
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值