`
Donald_Draper
  • 浏览: 999711 次
社区版块
存档分类
最新评论

AbstractExecutorService解析

    博客分类:
  • JUC
阅读更多
Executor接口的定义:http://donald-draper.iteye.com/blog/2365625
ExecutorService接口定义:http://donald-draper.iteye.com/blog/2365738
Future接口定义:http://donald-draper.iteye.com/blog/2365798
FutureTask解析:http://donald-draper.iteye.com/blog/2365980
CompletionService接口定义:http://donald-draper.iteye.com/blog/2366239
ExecutorCompletionService解析:http://donald-draper.iteye.com/blog/2366254
看这篇文章之前,对于没有接触过java并发包的朋友,建议将上面几个链接文章看完。
package java.util.concurrent;
import java.util.*;

/**
 * Provides default implementations of {@link ExecutorService}
 * execution methods. This class implements the <tt>submit</tt>,
 * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
 * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
 * to the {@link FutureTask} class provided in this package.  For example,
 * the implementation of <tt>submit(Runnable)</tt> creates an
 * associated <tt>RunnableFuture</tt> that is executed and
 * returned. Subclasses may override the <tt>newTaskFor</tt> methods
 * to return <tt>RunnableFuture</tt> implementations other than
 * <tt>FutureTask</tt>.
 *
 AbstractExecutorService提供了ExecutorService执行方法的默认实现。
submit,invokeAny,invokeAll方法主要通过newTaskFor方法返回一个RunnableFuture
,默认为FutureTask。比如FutureTask方法创建一个关联的RunnableFuture,并返回。
子类可以重写newTaskFor方法,返回一个除FutureTask之外的RunnableFuture接口实现。

 * <p> <b>Extension example</b>. Here is a sketch of a class
 * that customizes {@link ThreadPoolExecutor} to use
 * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
 下面是一个ThreadPoolExecutor实现范例,用CustomTask代替默认的FutureTask。
 *  <pre> {@code
 * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
 *
 *   static class CustomTask<V> implements RunnableFuture<V> {...}
 *
 *   protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
 *       return new CustomTask<V>(c);
 *   }
 *   protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
 *       return new CustomTask<V>(r, v);
 *   }
 *   // ... add constructors, etc.
 * }}</pre>
 *
 * @since 1.5
 * @author Doug Lea
 */
public abstract class AbstractExecutorService implements ExecutorService {
/**
     * Returns a <tt>RunnableFuture</tt> for the given runnable and default
     * value.
     *
     根据给定的Runnable和value,返回一个RunnableFuture,实际为FutureTask
     * @param runnable the runnable task being wrapped
     * @param value the default value for the returned future
     * @return a <tt>RunnableFuture</tt> which when run will run the
     * underlying runnable and which, as a <tt>Future</tt>, will yield
     * the given value as its result and provide for cancellation of
     * the underlying task.
     * @since 1.6
     */
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
    /**
     * Returns a <tt>RunnableFuture</tt> for the given callable task.
     *
     根据Callable,返回一个RunnableFuture,实际为FutureTask
     * @param callable the callable task being wrapped
     * @return a <tt>RunnableFuture</tt> which when run will call the
     * underlying callable and which, as a <tt>Future</tt>, will yield
     * the callable's result as its result and provide for
     * cancellation of the underlying task.
     * @since 1.6
     */
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
     /**
     提交,执行一个返回值为void的Runnable任务
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
	//创建任务
        RunnableFuture<Void> ftask = newTaskFor(task, null);
	//实际在Executor为抽象方法,待子类扩展
        execute(ftask);
        return ftask;
    }
    /**
     提交,执行一个返回值为T的Runnable任务,与submit(Runnable task)方法,基本没区别
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    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;
    }
    
    /**
    提交,执行一个Callable任务
     * @throws RejectedExecutionException {@inheritDoc}
     * @throws NullPointerException       {@inheritDoc}
     */
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
	//创建任务
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    //执行Callable任务集
     public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
	    //遍历任务集合,创建相应的RunnableFuture任务,并添加到结果集
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
	    //遍历结果集,等待所有任务执行完
            for (Future<T> f : futures) {
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            done = true;
	    //执行完,返回结果集
            return futures;
        } finally {
            if (!done)
	        //如果任务未执行完,遍历结果集,取消任务
                for (Future<T> f : futures)
                    f.cancel(true);
        }
    }
    //超时执行Callable任务集
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null || unit == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            long lastTime = System.nanoTime();
            //与非超时执行任务集不同的点是,在每次执行任务,判断是否超时,超时则返回结果集
            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            Iterator<Future<T>> it = futures.iterator();
            while (it.hasNext()) {
                execute((Runnable)(it.next()));
                long now = System.nanoTime();
                nanos -= now - lastTime;//nanos = nanos - (now - lastTime),剩下超时时间
                lastTime = now;
                if (nanos <= 0)
                    return futures;
            }

            for (Future<T> f : futures) {
                if (!f.isDone()) {
                    if (nanos <= 0)
                        return futures;
                    try {
		        //另一个不同点,为超时等待任务线程执行完
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    long now = System.nanoTime();
                    nanos -= now - lastTime;//nanos = nanos - (now - lastTime),剩下超时时间
                    lastTime = now;
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (Future<T> f : futures)
                    f.cancel(true);
        }
    }
}

超时执行Callable任务集,与非超时执行任务集不同的点是,
第一点:在每次执行任务,判断是否超时,超时则返回结果集;
第二点:在等待线程任务结束时,为超时等待;
再来看InvokeAny方法:
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
	    //委托给doInvokeAny
            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 {
	//委托给doInvokeAny
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }

 /**
     * the main mechanics of invokeAny.
     */
    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();
        List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
        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;
            long lastTime = timed ? System.nanoTime() : 0;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // Start one task for sure; the rest incrementally
	    //确保有一个任务在执行,余下的自动增长
            futures.add(ecs.submit(it.next()));
	    //剩余任务数量自减,任务激活数量赋1
            --ntasks;
            int active = 1;

            for (;;) {
	        //从完成任务执行器poll一个任务结果,这个我们在ExecutorCompletionService,
		//那篇文章中,有说,这里不再说
                Future<T> f = ecs.poll();
		
                if (f == null) {
		    //如果没有任务完成,则提交任务到执行器,剩余任务数量自减,任务激活数量自增
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)
		        //如果所有任务已经在跑,且激活数量任务数量为0,则跳出自旋
                        break;
                    else if (timed) {
		        //如果是超时,则超时poll
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        long now = System.nanoTime();
			//重新计算剩余超时时间
                        nanos -= now - lastTime;
                        lastTime = now;
                    }
                    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 (Future<T> f : futures)
	        //取消完成的任务
                f.cancel(true);
        }
    }

invokeAny的任务集,主要通过ExecutorCompletionService去执行,
当有任务执行结束时,获取执行结果,并取消其他任务。

总结:
无论是提交Runnable任务,还是Callable都是创建FutureTask执行任务,然后执行,返回结果。执行Callable任务集,遍历任务集合,创建相应的RunnableFuture任务,并添加到结果集;遍历结果集,等待所有任务执行完。超时执行Callable任务集,与非超时执行任务集不同的点是,第一点:在每次执行任务,判断是否超时,超时则返回结果集;第二点:在等待线程任务结束时,为超时等待。invokeAny的任务集,主要通ExecutorCompletionService去执行,当有任务执行结束时,获取执行结果,并取消其他任务。
分享到:
评论

相关推荐

    美团动态线程池实践思路开源项目(DynamicTp),线程池源码解析及通知告警篇.doc

    美团动态线程池实践思路开源项目(DynamicTp)线程池源码解析及通知告警篇 本文详细介绍了美团动态线程池实践思路开源项目(DynamicTp)的通知告警模块,该模块提供了多种通知告警功能,每一个通知项都可以独立配置...

    高并发编程,高并发编程,高并发编程

    * AbstractExecutorService是Java中的抽象线程池类,提供了execute()和submit()方法的默认实现。 七、高并发编程的其他知识点 * volatile关键字可以确保变量的可见性和原子性。 * synchronized关键字可以确保方法...

    Randroid类库

    19. **AbstractExecutorService**:提供了ExecutorService执行方法的默认实现,是线程池服务的基础。 20. **AbstractHttpClient**:这是HttpClient的便利基类,用于HTTP客户端的实现,简化了网络请求的处理。 21. ...

    java Fork Join框架及使用

    ForkJoinPool是这个框架的核心组件,它扩展了AbstractExecutorService类,并实现了工作窃取算法。工作窃取算法允许工作线程在自己的任务队列为空时,从其他线程的任务队列中偷取任务来执行,这样可以更高效地利用...

    JUC并发编程「公开课第三讲」.pdf

    - **Executor→ExecutorService→AbstractExecutorService→ThreadPoolExecutor**:这是线程池实现的基本层次结构,其中`ThreadPoolExecutor`是核心类,提供了线程池的核心功能。 - **工具类Executors**: 类似于`...

    MyThreadPool

    《深入解析Java线程池:MyThreadPool》 在Java编程中,线程池是一种非常重要的并发处理机制。本文将深入探讨自定义线程池——MyThreadPool的实现原理、设计模式以及如何有效地使用线程池来优化系统性能。线程池通过...

Global site tag (gtag.js) - Google Analytics