jdk源码:线程池ThreadPoolExecutor深入

1.ThreadPoolExecutor继承类图

              继承类图
  

. Executor
public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
     //向Executor提交一个任务,任务可能在当前线程执行,也可能在其他线程执行,或者在线程池执行取决于具体实现
    void execute(Runnable command);
}
. ExecutorService
//该接口提供停止(shutdown())与跟踪异步任务的方法(submit()返回一个Future)


//ExecutorService可以被关闭,当已经关闭将会拒绝新的任务。有两个方法提供来关闭一个
// ExecutorService:shutdown()允许先前提交任务执行完,shutdownNow()会停止所有
 // 正在执行的任务。当没有正在或等待执行的任务,并且没有任务被提交,线程池处于termination状态
 /**
     *一种优雅关闭线程池的方法:
 * void shutdownAndAwaitTermination(ExecutorService pool) {
 *   pool.shutdown(); // 拒绝接受新的任务
 *   try {
 *     // 先等待timeout时间,线程池是否处于停止状态
 *     //如果线程池已经处于termination状态,结束,否则
 *     //调用shutdownNow()立即停止所有活动任务(通过Thread.interrupt()来停止)
 *     //再次检查线程池是否处于停止状态(因为有些线程不可以Thread.interrupt()来停止),
 *    //如果停止,结束,否则,打印信息。
 *     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
 *       pool.shutdownNow(); // Cancel currently executing tasks
 *       // Wait a while for tasks to respond to being cancelled
 *       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
 *           System.err.println("Pool did not terminate");
 *     }
 *   } catch (InterruptedException ie) {
 *     // (Re-)Cancel if current thread also interrupted
 *     //线程在等待的过程中,被打断,直接调用shutdownNow()
 *     pool.shutdownNow();
 *     // Preserve interrupt status
 *     //恢复interrupt的标志位
 *     Thread.currentThread().interrupt();
 *   }
 * }}<
 */
public interface ExecutorService extends Executor {
    //不接收新的task,会继续执行已经提交的任务
    void shutdown();
    //通过interrupt停止所有task,用interrupt停止不了的task任务会一直在执行,直到完成。也就是
    //该方法不保证所有任务会被立刻停止。
    List<Runnable> shutdownNow();
    //检查线程池是否terminate
    boolean isTerminated();
    //检查线程池是否shutdown
    boolean isShutdown();
    //阻塞直到所有执行的任务完成在一个shutdown操作之后,或timeout时间已到,或当前线程被其他线程打断
    boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException;
    //提交有返回值得一个任务,返回一个代表任务待定结果的对象Future.Future的get()方法会阻塞直到任务完成
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    //其实是submit(Callable<T> task)的加强版,将集合中任务放进线程池来执行,接着返回一个List代表所有任务的结果
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
    //该方法加了一个timeout,当所有任务完成,或timeout时间过就会返回。其他未完成的任务就会被cancelled掉
    <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;  
}
. AbstractExecutorService
    //提供ExecutorService默认的实现,实现了submit和invokeAny和invokeAll.
public abstract class AbstractExecutorService implements ExecutorService {
    //将提交的任务封装成FutureTask,子类可以覆写这个方法,实现自己的封装
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    //这里用了模版的设计模式,子类通过overrid execute(task)即可
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    //这个方法主要实现invokeAny,当tasks中有一个任务完成就返回
    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                              boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (tasks == null)
            throw new NullPointerException();
        int ntasks = tasks.size();
        if (ntasks == 0)
            throw new IllegalArgumentException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //ExecutorCompletionService是对Exceutor的封装,这个类将提交的任务用其内部的
        //Executor来执行,将任务存储在一个BlockQueue中,供其他线程消费

        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);

        // For efficiency, especially in executors with limited
        // parallelism, check to see if previously submitted tasks are
        // done before submitting more of them. This interleaving
        // plus the exception mechanics account for messiness of main
        // loop.

        try {
            // Record exceptions so that if we fail to obtain any
            // result, we can throw the last exception we got.

            ExecutionException ee = null;
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();
            //提交第一个任务
            // Start one task for sure; the rest incrementally
            futures.add(ecs.submit(it.next()));
            --ntasks;
            int active = 1;

            for (;;) {
                //获取一次结果
                Future<T> f = ecs.poll();
                if (f == null) {
                    //没有执行完成,再执行下一个任务
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)
                        break;
                        //所有任务都开始执行了,阻塞等待第一个任务完成
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    else
                        f = ecs.take();
                }
                if (f != null) {
                    --active;
                    try {
                        return f.get();
                    } catch (ExecutionException eex) {
                        ee = eex;
                    } catch (RuntimeException rex) {
                        ee = new ExecutionException(rex);
                    }
                }
            }

            if (ee == null)
                ee = new ExecutionException();
            throw ee;

        } finally {
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            //开始所有任务
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
            //等待所有任务完成
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            for (int i = 0; i < size; i++) {
                execute((Runnable)futures.get(i));
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }

            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    nanos = deadline - System.nanoTime();
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }

}
}
. ThreadPoolExecutor

            线程池实现图
      这里写图片描述
下面是实现的具体细节

-线程池状态
 线程池的状态,通过一个ctl的字段来维护:

//ctl的高三位用来表示线程池的状态,剩下的位数用来表示线程的个数
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    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;
 RUNNING:接收新任务,并处理队列中的任务
 SHUTDOWN:不再接收新任务,但会继续处理未完成的任务,包括队列中的任务
 STOP:不再接收新任务,停止所有正在执行的任务,移除队列中的任务。
 TIDYING:所有任务都已经执行完了,并且worker线程的数量为0,队列中没有任务
 TERMINATED:完成terminated()的方法之后,就会进入该状态,只能从
             TIDYING状态转移该状态

各种状态的转移:
    RUNNING-》SHUTDWON :调用shutdown()方法后
    (RUNNIG,SHUTDOWN)-》STOP:调用shutdownNow()
    SHUTDOWN-》TIDYING:所有任务都已经执行完了,并且worker线程的数
                        量为   0,队列中没有任务
    STOP-》TIDYING:所有任务都已经执行完了,并且worker线程的数量为0,
                    队列中没有任务
    TIDYING-》:当terminate()钩子方法完成
-线程池的参数解析
ThreadPoolExecutor的构造器:
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)


/**1.corePoolSize:
*   如果线程个数小于coreSize每当有新任务来就会创建线程,尽管还有线程空闲.
    当线程数大于coreSize,当有新任务提交,会将新任务放入BlockQueue;
2.workQueue:
    用来保存提交的任务,当小于corePoolSize的线程在运行,线程池会创建线程来执行
    该任务而不是放入队列。当线程池运行的线程>=coreSize,线程池会将该任务放进
    阻塞队列,等待其他线程来执行。当阻塞队列已满并且线程的个数<maxPoolSize,线
    程池会创建新的线程来执行任务。当阻塞队列已满并且线程的个数==maxPoolSize,
    线程池就会拒接该请求。
3.keepAliveTime
    如果当前线程池的线程个数>corePoolSize,线程的空闲时间大于keepAliveTime将
    会被销毁。默认的情况下,当线程池的个数大于corePoolSize时,才会停止线程,也
    可以调用allowCoreThreadTimeOut(boolean)方法,使线程个数小于corePool
    Size时也会执行该策略。
4.unit
    keepAliveTime的单位
5.maxPoolSize
    最大的线程数
6.threadFactory
    线程池用来创建线程,用户可以自定义,例如,设置线程的优先级
7.handle
    线程池拒绝任务的策略。ThreadPoolExecutor默认实现了四种reject策略:
       CallerRunsPolicy: 直接再调用线程运行拒绝的任务
       public void rejectedExecution(Runnable r, //ThreadPoolExecutor     e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    AbortPolicy:抛出异常丢弃该任务
    public void rejectedExecution(Runnable r, //ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " 
+ r.toString() +
                                                 " //rejected from " +
                                                 //e.toString());
        }
    DiscardPolicy:什么事情都不干
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    DiscardOldestPolicy:移除阻塞队列中最老的任务,执行当前任务
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
*/
-线程池的具体实现:

1.内部类Worker(线程池的核心)

//worker代表一个线程,同时继承了AbstractQueuedSynchronizer,实现了一个非重入锁。为了
//AQS中的state是0表示是unlocked状态,1表示是locked状态。初始化AQS的state是-1,表示线程
    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /**
         * This class will never be serialized, but we provide a
         * serialVersionUID to suppress a javac warning.
         */
        private static final long serialVersionUID = 6138294804551838833L;

        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread; //线程
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;//初始任务
        /** Per-thread task counter */
        volatile long completedTasks;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
            setState(-1); //设置state为-1,禁止未runwork()就被intterupt
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);//处理任务
        }

        protected boolean isHeldExclusively() {
            return getState() != 0;
        }
        //尝试获取锁
        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
        //尝试释放锁
        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
        //获取锁
        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        //释放锁
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }
        //interrupt线程
        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }
/**不断从队列中获取任务并执行,处理所遇到的问题:
*  1.当遇到getTask()返回null,说明此时线程的状态或参数发生了变化。或者执行任务过程有常,
*    这时completedAbruptly为true,可能导致processWorkerExit创建一个新的线程来代替
* 2.每次执行任务前会执行beforeExecute,如果该方法抛出异常,将导致线程停止
* 3.假设beforeEecute正常执行,当执行任务时,会收集它抛出的任何异常并传给
* afterExecute。可能会接收到RunTimeException,Error,任意的Throwables,由于不能
* 在Runable.run()重新抛出Throwable,将Throwable封装成Error,再重新抛出
*/

    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts 将标志域设为0,可以被打断
        boolean completedAbruptly = true;//当线程由于没任务执行而退出时为false,由于异常退出为true.

        try {
            while (task != null || (task = getTask()) != null) {
                //防止在执行任务的过程中被打断,当调用shutdown()会尝试获取线程的锁trylock()
                //,获取成功才会停掉线程,调用shutdownNow()不会尝试获取线程的锁,直接停掉线程
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                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 = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }
    //处理线程的退出
    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }
        //线程的状态有可能改变为terminate
        tryTerminate();
        //不是抛异常退出,并且worker数少于min.创建线程替代
        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }

    //阻塞或超时等待任务

    /**返回null的情况:
    * 1.线程的个数大于maximumpoolSize(由于调用setMaximumPoolSize导致
    * maximumpoolSize改变)
    * 2.线程池状态为stop
    * 3.线程池状态为shutdown并且queue是空的
    * 4.线程等待超时,并且queue是空,该线程不是线程池最后的线程
    * if ((wc > maximumPoolSize || (timed && timedOut))
    *        && (wc > 1 || workQueue.isEmpty()))
    */
    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.
            //state是STOP以上的状态,直接停止Worker,如果是SHUTDOWN状态并且queue是空也停掉worker
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
            //当线程池的个数大于maximumPoolSize,当worker的时间超过keepalive并且
            //线程的个数大于1或者queue为空,
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;//不成功,重新检测条件
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();//阻塞等代任务
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                //线程池状态可能改变,retry
                timedOut = false;
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值