[JDK源码]-J.U.C-ThreadPoolExecutor

以下是在学习中整理的一些内容,如有错误点,多谢指出。

ThreadPoolExecutor线程池。
在这里插入图片描述

Executor

Excutor 是线程池的顶层接口。 定义了一个执行方法

public interface Executor {
    void execute(Runnable command);
}

传入一个Runnable对象,然后任务即可被执行。 抽象了一个Runnable 任务如何执行。

ExecutorService

ExcutorService 次级接口 在ExcutorService 中需要定义一些用于服务执行器的方法。

public interface ExecutorService extends Executor {
	//关闭服务
    void shutdown();
	//立即关闭服务
    List<Runnable> shutdownNow();
	//判断服务是否关闭
    boolean isShutdown();
	//判断服务是否完全终止
    boolean isTerminated();
	//等待当前服务停止
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
	//提交一个任务 Callable task 
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
	//提交一个任务Runnable task 
    Future<?> submit(Runnable task);
	//提交一组callable 任务执行
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
	//提交一组callable 任务执行....  这个包含了等待执行的时间
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;
	//提交一组任务,等待其中任何一个任务完成后返回
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
	//提交一组任务,等待其中任何一个任务完成后返回。 这里包含了等待执行的时间
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

ExcutorService 继承自Excutor,这表明了它既具备了执行器的特性,有增加了自身的功能,接口组合就是为了 功能合并。

AbstractExecutorService

AbstractExecutorService 封装了部分 ExecutorService 的方法,但是并没有实现线程池,就是 模板方法,定义了公用算法,对于execute执行并没有实现,所以它只能是一个抽象类。
在这里插入图片描述
submit 将对象封装,然后调用execute 方法执行。
invokeAny:->doInvokeAny方法,只要任何一个任务被执行完成就返回,然后取消其他任务
invokeAll :类似 invokeAny ,这里是执行所有传入的任务,然后等待任务执行完毕后返回

ThreadPoolExecutor

线程池:避免了创建和销毁的性能损耗。
组成:任务阻塞队列 BlockingQueue 线程容器 HashSet

源码中对几个状态的描述

/*
RUNNING: 运行  接受新任务并处理排队的任务  
SHUTDOWN: 关闭   不接受新任务,但处理队列中的任务  
STOP:停止   不接受新任务,不处理排队的任务,中断正在进行的任务  
TIDYING:转变   所有任务都已终止,workerCount为0,线程过渡到状态整理会运行terminated()钩子方法吗  
TERMINATED: 终止  TERMINATED()已完成  
状态的转换!!
RUNNING -> SHUTDOWN 
在调用shutdown()时,可能隐式地在finalize()中  
(RUNNING or SHUTDOWN) -> STOP
调用shutdownNow()  
 SHUTDOWN -> TIDYING
当队列和池都是空的  
STOP -> TIDYING
当池是空的 
TIDYING -> TERMINATED  
当terminated()钩子方法完成时,将运行terminated()钩子方法  
TERMINATED: TERMINATED()已完成  
*/

参数

//直接看下 全参的构造
public ThreadPoolExecutor(int corePoolSize, //核心
                              int maximumPoolSize,//最大
                              long keepAliveTime,//时间
                              TimeUnit unit, //单位
                              BlockingQueue<Runnable> workQueue,//队列
                              ThreadFactory threadFactory,//工厂
                              RejectedExecutionHandler handler)//拒绝
                              {}
//线程,时间单位,放在那,从哪拿,遭不住了怎么办。

ThreadPoolExecutor 属性与构造方法

public class ThreadPoolExecutor extends AbstractExecutorService {
    //通过一个原子性的Integer整型值 包含了workCount 工作线程数的 runState 运行状态  :ctl
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    // COUNT_BITS 29
    private static final int COUNT_BITS = Integer.SIZE - 3;
    //最大工作线程数
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    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;

    // 这 3个 用来在 ctl 中获取对应的信息
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }
	//用于缓存提交到线程池的任务队列。 
    private final BlockingQueue<Runnable> workQueue;
    //可重入锁
    private final ReentrantLock mainLock = new ReentrantLock();
	//用于保存所有线程池中的Woker对象的set集合
    private final HashSet<Worker> workers = new HashSet<Worker>();
	//支持awaitTerminate 的等待条件,即外部可以通过这个条件变量来等待线程池 termination(终止)
    private final Condition termination = mainLock.newCondition();
	//用于追踪线程池中出现过最大的线程数,需要上mainLock锁访问
    private int largestPoolSize;
	//统计线程已执行完成的任务数,当然这个值只在worker线程终结时进行更新,需要上mainLock锁访问
    private long completedTaskCount;
	//用户自定义的所有变量都可以通过volatile修饰保证线程可见性。创建线程的工厂
    private volatile ThreadFactory threadFactory;
	//线程池饱和后的拒绝策略
    private volatile RejectedExecutionHandler handler;
	//创建线程后的保活时间,由于线程创建后会消耗操作系统的系统资源,控制空闲多久回收
    private volatile long keepAliveTime;
	//是否允许核心线程数超时回收, 默认时false
    private volatile boolean allowCoreThreadTimeOut;
	//核心线程数大小
    private volatile int corePoolSize;
	//最大线程数大小
    private volatile int maximumPoolSize;
    //线程池饱和后的 默认拒绝策略
    private static final RejectedExecutionHandler defaultHandler =
       new AbortPolicy();
    
//内部类 Worker 用于封装线程和执行任务,继承了AQS 说明具有同步器的特性
    private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
        //worker 运行的线程对象。由用户提供的ThreadFactory创建
        final Thread thread;
        //初始执行的任务,可能为null
        Runnable firstTask;
        //当前worker 执行完成的任务数
        volatile long completedTasks;
         
        Worker(Runnable firstTask) {
            setState(-1); //设置state为 -1
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }
        public void run() {
            runWorker(this);
        }  
    }
//3个钩子函数:工作线程执行获得的任务前的回调;工作线程执行获得任务后的回调;在线程池由SHUTDOWN转为   terminated 时调用 
    protected void beforeExecute(Thread t, Runnable r) { }
    protected void afterExecute(Runnable r, Throwable t) { }
    protected void terminated() { }
    
//拒绝策略的实现
    //将任务交给生产线程来执行
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        public CallerRunsPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }
    //抛出异常..
    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() { }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }
    //将任务丢弃
    public static class DiscardPolicy implements RejectedExecutionHandler {
        public DiscardPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }
	//丢弃最早放入的任务
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        public DiscardOldestPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
  
}

execute方法的实现

public void execute(Runnable command) {
    if (command == null)//你要提交空任务吗?
        throw new NullPointerException();
    int c = ctl.get();//获取 ctl
    //如果当前工作线程小于核心线程数,那么调用addWorker添加工作线程直接返回
    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);
    }
    //到这里说明任务没有添加到任务队列中,由于任务队列已满,尝试添加worker执行任务。
    //如果添加失败 调用reject 来执行拒绝策略
    else if (!addWorker(command, false))
        reject(command);
}

addWorker

//向线程池中添加 worker  firstTask 为工作线程创建后第一个要执行的任务,core表明线程是否为核心线程
private boolean addWorker(Runnable firstTask, boolean core) {
    retry:
    for (;;) {//获取ctl的和 运行状态			
        int c = ctl.get(); 
        int rs = runStateOf(c);
        //要保证 SHUTDOWN状态不接受任务但要消费工作队列任务
        if (rs >= SHUTDOWN &&//线程池关闭了
            ! (rs == SHUTDOWN && //(不可以接受外部任务,但是需要执行内部队列的任务)
               firstTask == null &&//是不是新提交的任务
               ! workQueue.isEmpty()))//队列是否为空
            return false;

        for (;;) {//获取 workerCountOf
            int wc = workerCountOf(c);
            if (wc >= CAPACITY ||//如果工作线程数大于最大容量,则直接返回。
             //如果工作线程数量大于或等于corePoolSize 或者maximumPoolSize  直接返回
                wc >= (core ? corePoolSize : maximumPoolSize))//core  是 true 还是false 传进来的
                return false;
            //CAS 增加 workCount,如果成功 退出外层循环
            if (compareAndIncrementWorkerCount(c))
                break retry;
            c = ctl.get();  // 重新读取  
            if (runStateOf(c) != rs)//判断运行状态。如果改变了退出当前循环,
                continue retry;
        }
    }
     //此时workerCount+1 成功。但还没有创建线程。 创建Worker绑定thread并启动线程
    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 {
				//再次获取 判断线程池状态,然后将 worker添加到workers容器中
                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();
                    //判断是否添加后大于最大workers数量,如果超过,则赋值即可
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {//如果锁添加成功,那么启动线程即可 work里的 run方法
                t.start();
                workerStarted = true;
            }
        }
    } finally {
        //如果线程启动失败,则调用 addWorkerFailed方法恢复 workCount
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

addWorkerFailed

/*如果worker存在,将worker从worker队列中移除 还原workerCount调用tryTerminate方法 重新检查 runState */
private void addWorkerFailed(Worker w) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        if (w != null)
            workers.remove(w);
        decrementWorkerCount();
        tryTerminate();
    } finally {
        mainLock.unlock();
    }
}

线程启动实现原理

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

runWorker 方法

final void runWorker(Worker w) {
    //获取当前worker 绑定的线程和第一个需要执行的任务
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // 释放锁 
    //用于标识是不是因为业务异常导致的线程退出
    boolean completedAbruptly = true;
    try { // try的啥呢?
        // 开始调用getTask 从队列中获取任务执行
        while (task != null || (task = getTask()) != null) {
            w.lock();
            //用于确保线程池处于STOP状态时,线程处于中断状态
            if ((runStateAtLeast(ctl.get(), STOP) ||
                 (Thread.interrupted() &&
                  runStateAtLeast(ctl.get(), STOP))) &&
                !wt.isInterrupted())// 看你是不是中断 (清除标记位)
                wt.interrupt();//设置中断标志位
            try {
                //钩子函数
                beforeExecute(wt, task);
                //用于封装执行的异常对象
                Throwable thrown = null;
                try {
                    //开始执行获取到的任务
                    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任务关联,然后增加完成任务数,释放worker lock
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        //线程的正常结束,设置标志位为false
        completedAbruptly = false;//导致它等于 true 的情况 ? 
    } finally {
        //调用 这个方法来执行一些清理操作
        processWorkerExit(w, completedAbruptly);
    }
}

getTaks 方法

//用于 worker中获取执行任务
private Runnable getTask() {
    boolean timedOut = false; // poll方法是否超时

    for (;;) {//获取 ctl运行状态 
        int c = ctl.get();
        int rs = runStateOf(c);
        // 检查运行状态
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();//减少一个 workCount CAS wc
            return null;
        }
		
        int wc = workerCountOf(c);
		//看看是否允许超时。这里条件为 允许核心线程超时或当前工作线程大于核心线程数
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
		/*如果工作线程大于 最大线程数 ,或者允许超时且工作线程数大于1, 
		 或者任务队列为空 	*/
        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))//减少 工作线程数 ,然后返回null
                return null;
            continue;
        }
		//如果允许超时
        try {
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : //等待某一段时间返回
                workQueue.take();//通过take 阻塞
            if (r != null)
                return r;
            //等待超时,因为返回的Runnable任务 为null
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;//进入这里  回退for循环开始重新进行
        }
    }
}

processWorkerExit方法

//在worker线程执行任务完毕后,执行清理工作。 
private void processWorkerExit(Worker w, boolean completedAbruptly) {
//completedAbruptly 标识 worker 线程退出或者是否由于用户任务异常导致的退出
    if (completedAbruptly) // 如果是意外退出 decrementWorkerCount方法
        decrementWorkerCount();
	//如果 mianLock 保证并发安全
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //completedTaskCount 增加当前worker完成的任务数,然后从workers数组中移除worker
        completedTaskCount += w.completedTasks;
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }
	//调用tryTerminate 检查运行状态
    tryTerminate();
    int c = ctl.get();
    //如果运行状态小于 STOP ,即处于RUNNING 或 SHUTDOWN,增加worker的数量
    if (runStateLessThan(c, STOP)) {
        if (!completedAbruptly) {//是不是由于用户线程导致的
        //根据allowCoreThreadTimeOut 来设置min为0 或核心线程数 corePoolSize。
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
            if (min == 0 && ! workQueue.isEmpty())
                min = 1;//保证线程能够执行任务(因为任务队列还有任务等待),最小值min 设置为1
            if (workerCountOf(c) >= min)
                return; 
        }
        addWorker(null, false);//如果是 用户导致的异常 (新起了一个新的线程)
    }
}

shutdown 方法

//执行线程池 shutdown操作
public void shutdown() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        checkShutdownAccess();//检测访问权限
        advanceRunState(SHUTDOWN);//改变状态
        interruptIdleWorkers();//中断空闲线程  是不是空闲线程需要看 runWork  getTask 
        onShutdown(); // 执行它 是个钩子函数(ScheduledThreadPoolExecutor()看它的时候它重写了这个方法,其他与 ThreadPoolExecutor shutdown没啥区别)
    } finally {
        mainLock.unlock();
    }
    tryTerminate();//调用它 实现
}
//改变状态的方法
private void advanceRunState(int targetState) {
    for (;;) {//死循环 CAS 来改变 
        int c = ctl.get();
        if (runStateAtLeast(c, targetState) ||
            ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
            break;
    }
}

interruptIdleWorkers中断空闲线程

private void interruptIdleWorkers() {//通过这个调用interruptIdleWorkers 
    interruptIdleWorkers(false);//中断空闲线程   false
}
//中断所有未中断的且正在等待的任务执行的线程,如果设置了onlyOne(默认ture),则只中断其中一个线程
private void interruptIdleWorkers(boolean onlyOne) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (Worker w : workers) {
            Thread t = w.thread;
            //条件: 未中断 && 正在等待任务执行的线程
            if (!t.isInterrupted() && w.tryLock()) {
                try {//没有中断 获得了锁 就把它中断 
                    t.interrupt();
                } catch (SecurityException ignore) {
                } finally {
                    w.unlock();
                }
            }
            //如果设置了onlyOne ,则唤醒一个  break
            if (onlyOne)
                break;
        }
    } finally {
        mainLock.unlock();
    }
}
//执行完毕之后 所有的线程 被中断 空闲线程 已经退出了

tryTerminate方法

//尝试转换状态为 TERMINATED  	这个方法所有的线程都会走
final void tryTerminate() {
    for (;;) {
        int c = ctl.get();
        //若线程池正在执行任务|| 处于 TIDYING 或 (TERMINATED && 任务队列非空),直接返回
        if (isRunning(c) ||
            runStateAtLeast(c, TIDYING) ||
            (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
            return;
        if (workerCountOf(c) != 0) { 
            interruptIdleWorkers(ONLY_ONE); //只中断一个,如果所有全部中断 会怎样?
            return;	
        }
		/*如果worker为0,则表明线程池中已经没有等待任务和线程,调用termination()后设置线程池状态为 TERMINATED,然后唤醒所有等待线程池 TERMINATED 的其他线程  整个全部完结 线程池全部终结*/
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {//状态变为TIDYING
                try {
                    terminated();//执行这个
                } finally {
                    ctl.set(ctlOf(TERMINATED, 0));//再把状态  TERMINATED
                    termination.signalAll();//这个 就是 唤醒所有的等待 TERMINATED 的线程 ,
                }
                return;
            }
        } finally {
            mainLock.unlock();
        }
    }
}

shutdownNow方法

//与shutdown不同的就是  这个就是 STOP ! SHUTDOWN STOP的区别?
public List<Runnable> shutdownNow() {
    List<Runnable> tasks;
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {//转变状态为STOP,
        checkShutdownAccess();
        advanceRunState(STOP);
        interruptWorkers();
        tasks = drainQueue();//我不执行队列里的任务  把任务从队列里取出来 返回出来 
    } finally {
        mainLock.unlock();
    }
    tryTerminate();
    return tasks;
}

interruptWorkers中断所有

private void interruptWorkers() {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (Worker w : workers)//就是遍历 所有工作线程
            w.interruptIfStarted();
    } finally {
        mainLock.unlock();
    }
}

void interruptIfStarted() {
    Thread t;
    //已经启动, 当前不为null 没有被中断  进行中断
    if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
        try {
            t.interrupt();
        } catch (SecurityException ignore) {
        }
    }
}

drainQueue

private List<Runnable> drainQueue() {
    BlockingQueue<Runnable> q = workQueue;
    ArrayList<Runnable> taskList = new ArrayList<Runnable>();
    //先尝试将队列导出到列表中
    q.drainTo(taskList);
    //如果阻塞队列不支持 drainTo操作,那么手动将其挨个移除
    if (!q.isEmpty()) {
        for (Runnable r : q.toArray(new Runnable[0])) {
            if (q.remove(r))
                taskList.add(r);
        }
    }
    return taskList;
}

romove 方法 用于将任务从队列中移除

//从任务队列里移除指定的任务
public boolean remove(Runnable task) {
    boolean removed = workQueue.remove(task);
    //尝试将SHUTDOWN状态的线程池变为 TERMINATE状态。
    tryTerminate(); 
    return removed;
}

awaitTerminationf方法

//由外部线程调用,等待线程池完全被终止
public boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException {
    long nanos = unit.toNanos(timeout);
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        /*循环等待线程结束,首先判断是否已处于TERMINATED 终止状态,然后判断nanos是否小于或等于0,
         如果是,则不等待,直接返回;否则调用 termination 条件变量等待超时*/
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }
}

以上是部分整理,没有进行完全整理,可以在其中整理出来。

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值