线程池源码分析(1)execute()方法

接下来,我将讲解线程池的源码分析。作为新手入门的手册的话,我就选取曾经自己看的文章,写的相当不错。https://www.jianshu.com/p/210eab345423

1.从最简单的单线程-线程池入手。

//一点点的进行分析。首先,放出第一种用法。
ExecutorService executor=Executors.newSingleThreadExecutor();
//只需要实现Runnable接口即可
Runnable command=new YourJob();
executor.execute(command);

//(1)构造函数
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService(
           new ThreadPoolExecutor(1, 1,0L,TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>()));
}
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
}
//首先针对参数讲解一下
(1) 核心线程数
(2) 线程总数
(3) 非核心线程存活时间(不干活后存活时间)
(4) 时间单位
(5) 工作队列
(6) 默认的线程工厂:应该是用来生产线程的
(7) 拒绝策略

//从上面的入参可以知道,单线程的线程池,只有一个线程。

//调用debug模式:执行execute(runnable)方法
public void execute(Runnable command) {
    if (command == null)    
        throw new NullPointerException();
    //ctl是一个原子Integer,代表的是工作的线程数量
    //private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    //ctl=-536870911
    int c = ctl.get();
    //如果工作线程数量小于核心线程数,就添加工作者
    if (workerCountOf(c) < corePoolSize) {
        if (addWorker(command, true))
            return;
        c = ctl.get();
    }
    //将任务放入到队列当中
    //单线程-池:队列的长度为Integer.MAX_VALUE
    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);
}

//添加工作者
private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {
        int c = ctl.get();
        //判断线程数有没有超过总容量:会返回ctl
        int rs = runStateOf(c);
        //检查 工作队列是否是空的
        if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null &&
                                  !workQueue.isEmpty()))
            return false;
        for (;;) {
            int wc = workerCountOf(c);
            //判断是否大于线程总容量;
            //core为true的话,判断正在工作的线程和 核心线程的数量关系。
            //core为false的话,判断正在工作的线程和 最大线程数的数量关系
            //当正在工作的线程,视情况,大于任何一个的时候都会返回false,即添加任务失败
            if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
            //添加任务成功
            if (compareAndIncrementWorkerCount(c))
                break retry;
            c = ctl.get(); //再次读取,是因为多线程下,ctl会改变
            if (runStateOf(c) != rs) 
                continue retry;
        }
    }
    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)) {
                    //验证新建的线程是否还未start和活着
                    if (t.isAlive()) 
                        throw new IllegalThreadStateException();
                    //为什么要把work放入set中?
                    workers.add(w);
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                //启动线程
                t.start();
                workerStarted = true;
            }
        }    
    } finally {
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        //从队列当中获取任务:这里会进行阻塞,并且这还和线程回收有关,放在后面
        while (task != null || (task = getTask()) != null) {
            w.lock();
            if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted())
            wt.interrupt();
        try {
            //执行前处理:空实现
            beforeExecute(wt, task);
            Throwable thrown = null;
            try {
                //执行队列中的run。这个地方就不会是新建线程处理了
                //而是核心线程直接调用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;
            w.completedTasks++;
            w.unlock();
        }
    }
    completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

现在我们来看看前面提到的getTask()方法造成的阻塞并回收线程。

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            //wc就是指目前工作线程数量,这样其实就没有核心不核心线程的概念了
            //只要超过了,不管是哪个线程走到这里,然后就会被回收
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                //回收计数
                if (compareAndDecrementWorkerCount(c))
                    //然后进入线程的runWork方法中的finally里的方法
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值