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

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去执行,当有任务执行结束时,获取执行结果,并取消其他任务。
分享到:
评论

相关推荐

    3_AbstractExecutorService源码阅读1

    `AbstractExecutorService`是Java并发编程中的一个关键抽象类,它是`ExecutorService`接口的一个实现基础。`ExecutorService`接口是`java.util.concurrent`包的一部分,用于管理和控制线程的执行,提供了一种将任务...

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

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

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

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

    AbrastractExecutorService

    `AbstractExecutorService`是Java并发工具包`java.util.concurrent`中的一个抽象类,它提供了`ExecutorService`接口的基本实现框架。`ExecutorService`接口是`Executor`接口的一个扩展,主要负责管理和控制线程的...

    Randroid类库

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

    线程池核心组件源码剖析.docx

    在Java中,线程池的核心组件主要包括四个部分:`Executor`接口、`ExecutorService`接口、`AbstractExecutorService`抽象类以及`ThreadPoolExecutor`实现类。此外,`Executors`工具类提供了方便的线程池创建方法。 1...

    java Fork Join框架及使用

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

    Java使用ExecutorService来停止线程服务

    在上面的代码中,我们继承了 AbstractExecutorService 类,并添加了一个 taskCancelledAtShutdown 集合来存储那些已经开始执行但是没有执行完毕的任务。在 execute() 方法中,我们使用 finally 语句来判断任务是否...

    了解Java线程池创建过程

    Java中提供了一个名为Executor框架的线程池管理框架,该框架包括Executor、ExecutorService、AbstractExecutorService和ThreadPoolExecutor等接口和类。Executor是一个基本的接口,提供了execute方法来执行Runnable...

    J2SE 1.6所有的类

    在并发编程中,`AbstractExecutorService`是`ExecutorService`的一个抽象实现,提供了管理和控制线程池的方法。`AbstractInterruptibleChannel`代表可以被中断的通道,是NIO的一部分。`AbstractQueuedSynchronizer`...

    MyThreadPool

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

    深入理解高并发编程-Java线程池核心技术

    线程池中的重要顶层接口和抽象类,如ExecutorService、AbstractExecutorService和ScheduledExecutorService,提供了基础的线程池服务和调度功能。这些接口和抽象类为开发者构建和定制线程池提供了灵活性,可以根据...

    java中文帮助文档[归类].pdf

    5. **并发编程**:AbstractExecutorService、AbstractInterruptibleChannel和AbstractQueuedSynchronizer等类是Java并发库的核心组件,它们支持线程池、通道操作和同步原语。 6. **文档模型**:AbstractDocument...

    徒手实现线程池-1

    - AbstractExecutorService 抽象类进一步简化了 ExecutorService 的实现。 - ThreadPoolExecutor 是具体实现类,负责管理和调度线程。 - ScheduledExecutorService 提供了定时和周期性任务的执行能力。 了解并...

    我的线程池

    在实际应用中,还可以自定义线程池实现,例如继承`AbstractExecutorService`或实现`ExecutorService`接口,以满足特定的业务需求。例如,可以定制线程的优先级、线程的命名规则、异常处理策略等。 总的来说,线程池...

    BATJ面试题汇总及详解65页

    - **创建线程池的方式**:Java中可通过`Executors`工厂类或直接继承`AbstractExecutorService`实现自定义线程池。 - **线程安全问题**:线程安全是指在多线程环境下,代码能够正确处理并发访问,不会导致数据不...

    java中文帮助文档.pdf

    `AbstractExecutorService`是`ExecutorService`的抽象类,提供了线程池服务的基本实现。`AbstractInterruptibleChannel`是可中断通道的抽象类,允许在读写操作时被中断。`AbstractLayoutCache`和`...

    线程池java

    该类继承自`AbstractExecutorService`,实现了线程池的主要功能。 **构造方法详解**: ```java public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, ...

    java.util.concurrent.uml.pdf

    AbstractExecutorService是一个抽象类,实现了ExecutorService接口,并提供了一些默认实现,以便于子类进行更具体的实现。 ThreadPoolExecutor是一个核心的线程池实现,它通过线程池参数配置来管理执行任务。它实现...

Global site tag (gtag.js) - Google Analytics