ThreadPoolExecutor线程池源码分析

1,236 阅读2分钟

1、Thread、Runnable

  • Runnable接口,定义run()方法。
  • Thread类实现Runnable接口,重写run()方法。

image-20210415162643757.png

2、Callable

  • Callable接口,定义call()方法。

image-20210415162918402.png

3、Executor、AbstractExecutorService、ExecutorService、ThreadPoolExecutor

  • Executor接口,定义execute()方法,只接收 Runnable 对象。
  • ExecutorService接口,定义submit()方法,既可以支持 Runnable ,也支持 Callable。
  • AbstractExecutorService类,实现ExecutorService接口,重写submit()方法。
  • ThreadPoolExecutor类,继承AbstractExecutorService类,重写execute()。

image-20210415162159612.png

4、Future、RunnableFuture、FutureTask

  • Future接口,定义get()方法。
  • RunnableFuture接口,继承Runalbe接口和Future接口,一般用来将Callable 转换为 Runnable,也可以得到返回值。
  • FutureTask类,实现RunnableFuture接口,执行run()方法。

image-20210415162305890.png

5、举例

  • 新建一个线程池
ExecutorService executorService = new ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • 构造Callable/Runnable类,重写Call/Run方法,实现任务的业务逻辑
new Callable<Object>(){
            @Override
            public Object call() throws Exception {

                return "hello,ThreadPool";
            }
        };
  • 调用线程池的submit方法提交任务,得到一个Future对象
Future<Object> future = executorService.submit(callable);
  • ThreadPoolExecutor继承AbstractExecutorService类,没有重写submit方法,故ExecutorService的submit方法在AbstractExecutorService类中实现
public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}
  • 将Callable/Runnable对象转成RunnableFuture对象,后执行execute方法,具体实现是在ThreadPoolExecutor类里面完成,下面对源码做了删减,其中主要是执行了addWorker方法,提交了任务,如果addWorker方法执行成功,则返回。
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
    }
  • addWorker方法做了删减如下,其中就是要将Runnable对象作为参数构建Worker对象,将Worker对象里面的线程拿到后执行start方法
    private boolean addWorker(Runnable firstTask, boolean core) {
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
           
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } 
        return workerStarted;
    }

  • Worker对象定义如下,实现了Runnable接口,继承AQS类。可以看到Worker构造方法中,传入一个Runnable对象,同时会用此Runnable对象作为参数新建一个线程(没有启动)。上面调用start方法其实就是启动了线程,且start方法会调用了Worker对象的run方法。
private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable{
  Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }
  public void run() {
            runWorker(this);
        }
}
  • Worker对象的run方法实际是调用了runWorker方法,里面再调用了run方法。问题:为什么要做这一步
    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        
                    try {
                        task.run();
                        afterExecute(task, null);
                    } 
    }
  • 上面的run方法实际是执行了FutureTask类的run方法。
public class FutureTask<V> implements RunnableFuture<V> {
  
  public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
  
  public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

}
  • 不管是Runnable还是Callable对象,都会转成Callable对象,执行的run方法如下
    public void run() {
       
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                }
              if (ran)
                    set(result);
            }
        }
    }
  • 看到在run方法中会执行Callable对象的call方法,返回的结果,通过set方法放进outcome中(CAS
    protected void set(V v) {
        if (STATE.compareAndSet(this, NEW, COMPLETING)) {
            outcome = v;
            STATE.setRelease(this, NORMAL); // final state
            finishCompletion();
        }
    }
  • 调用get方法获得任务执行结果
try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
  • get方法调用了report方法
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }
  • report方法将outcome值返回输出
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }