线程池源码分析(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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40384690/article/details/82670190