AbstractExecutorService源码
public class RunnableFutureTask {
    static FinalizableDelegatedExecutorService executorService = (FinalizableDelegatedExecutorService) Executors1.newSingleThreadExecutor();    //创建一个单线程执行器
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        futureDemo();
    }
    static void futureDemo() throws InterruptedException, ExecutionException {
            /*调用FinalizableDelegatedExecutorService的submit,转调ThreadPoolExecutor1的submit,
            转调父类AbstractExecutorService1的submit,提交给线程池的是一个FutureTask,线程池里面调用runWorker(),
            然后Runnable的run方法,就是FutureTask的run方法(开了线程池的一个线程去执行),executorService.submit线程退出到外层。
            FutureTask的run方法没有返回值,结果是在FutureTask的outcome属性里面的。result2.get()就是获取FutureTask的outcome属性。*/
            Future<String> result2 = executorService.submit(new Callable<String>()     {
                public String call() throws Exception {
                    return "result2";
                }
            });
            System.out.println("future result from callable:"+result2.get());
            //executorService.submit会把Callable封装成FutureTask然后丢到线程池执行,结果在FutureTask自身中。
            FutureTask1<String> result3 = new FutureTask1<String>(new Callable<String>() {
                public String call() throws Exception {
                    return "result3";
                }
            });
            executorService.submit(result3);
            /*submit会把result3再封装为FutureTask,丢到线程池执行,线程池最后执行runWorker(),然后Runnable的run方法,
            就是外层FutureTask的run方法(开了线程池的一个线程去执行),外层FutureTask run()时候调用里面result3的call方法,
            result3作为一个Runnable已经被封装为了一个Callable,就嗲用封装的call(),转为调用里面真正result3的run方法,
            result3的run方法执行时候,调用里面匿名内部类的call(),设置结果给result3。*/
            System.out.println("future result from FutureTask:" + result3.get());     
    }
}
public abstract class AbstractExecutorService1 implements ExecutorService {
    // 对Runnable的封装,T是期望值
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask1<T>(runnable, value);
    }
    // 对Callable的封装
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask1<T>(callable);// FutureTask1是一个Runnable,也就是通过execute提交给ThreadPoolExecutor线程池的一个任务
    }
    // Runnable封装为FutureTask,把FutureTask(是一个Runnable)作为任务丢到线程池执行,并且返回这个FutureTask。从FutureTask得到执行结果。
    public Future<?> submit(Runnable task) {
        if (task == null)
            throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);// FutureTask1
        execute(ftask);
        return ftask;// ftask是一个Runnable,也就是通过execute提交给ThreadPoolExecutor线程池的一个任务
        // 从ftask FutureTask获取结果
    }
    // Runnable封装为FutureTask,把FutureTask(是一个Runnable)作为任务丢到线程池执行,并且返回这个FutureTask。。从FutureTask得到执行结果。
    // T是期望值
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);// FutureTask1
        execute(ftask);
        return ftask;// 从ftask FutureTask获取结果
    }
    // Callable封装为FutureTask,把FutureTask(是一个Runnable)作为任务丢到线程池执行,并且返回这个FutureTask。。从FutureTask得到执行结果。
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null)
            throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);// FutureTask1
        execute(ftask);
        return ftask;// 从ftask FutureTask获取结果
    }
    // invokeAny()和invokeAll()方法是以批量的形式执行一组任务,然后等待至少一个或者全部的任务完成。
    //一批任务中的某个任务完成了,就返回他的结果,所以他返回的是最快执行完成的那个任务的结果,他的重载方法,加入了超时机制,如果超过了限制的时间也没有一个任务完成,那么就会抛出超时异常了。
    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 == )
            throw new IllegalArgumentException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        ExecutorCompletionService1<T> ecs = new ExecutorCompletionService1<T>(this);
        // 为了提高效率,特别是在并行性有限的执行器中,请在提交更多任务之前检查以前提交的任务是否已完成。这种交织加上异常机制解释了主循环的混乱。
        try {
            // 记录异常,以便如果我们无法获得任何结果,我们可以抛出最后一个异常。
            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 = ;
            for (;;) {
                Future<T> f = ecs.poll();
                if (f == null) {
                    if (ntasks > ) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    } else if (active == )
                        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 = (ExecutionException) new Exception();
            throw ee;
        } finally {
            for (int i = , 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, );
        } 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));
    }
    //批量提交并执行任务,当所有任务都执行完成时,返回一个保存任务状态和执行结果的Future列表。
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
        if (tasks == null)// 如果任务集后为空,则抛出一个NullPointerException
            throw new NullPointerException();
        // 创建一个和任务数量等大的ArrayList.
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;//标志任务是否完成
        try {
            //将tasks里面的每个Callable转化成Future,添加到futures里面,并交给Executor#execute()方法执行
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);// FutureTask1
                futures.add(f);
                execute(f);
            }
            //判断futures里面的Future是否执行结束,如果还没有完成,通过get()阻塞直到任务完成
            //也是就说执行完这一段代码,futures里面的每一个任务都是执行完成的情况
            for (int i = , 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 = , size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);//采用中断线程的方式取消任务
        }
    }
    //重载方法也是类似的,就是加入了一个超时时间,不管是所有的任务都执行完,还是已经到达超时的时间,只有两个有中满足其中一个,就会返回一个保存任务状态和执行结果的Future列表。
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
            throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();//如果任务集后为空,则抛出一个NullPointerException
        long nanos = unit.toNanos(timeout);//将超时时间转化成纳秒
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());//创建一个和任务数量等大的ArrayList.
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));//将tasks里面的每个Callable转化成Future,添加到futures里面
            final long deadline = System.nanoTime() + nanos;//超时时间点
            final int size = futures.size();//记录一下futures的大小,
            //执行任务,如果超时就直接返回futures
            for (int i = ; i < size; i++) {
                execute((Runnable) futures.get(i));
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }
            //判断futures里面的Future是否执行结束,如果还没有完成,通过get()阻塞直到任务完成
            //也是就说执行完这一段代码,要么futures里面的每一个任务都是执行完成了,要么就是超时了
            for (int i = ; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                        f.get(nanos, TimeUnit.NANOSECONDS);//这里捕捉了get()方法可能出现了所有的异常
                    } 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 = , size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);//采用中断线程的方式取消任务
        }
    }
}
AbstractExecutorService源码的更多相关文章
- 【JUC】JDK1.8源码分析之ThreadPoolExecutor(一)
		一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ... 
- 【原创】JAVA并发编程——Callable和Future源码初探
		JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ... 
- Java并发包源码学习之线程池(一)ThreadPoolExecutor源码分析
		Java中使用线程池技术一般都是使用Executors这个工厂类,它提供了非常简单方法来创建各种类型的线程池: public static ExecutorService newFixedThread ... 
- ThreadPoolExecutor的应用和实现分析(中)—— 任务处理相关源码分析 线程利用(转)
		前面一篇文章从Executors中的工厂方法入手,已经对ThreadPoolExecutor的构造和使用做了一些整理.而这篇文章,我们将接着前面的介绍,从源码实现上对ThreadPoolExecuto ... 
- [转载] Java线程池框架源码分析
		转载自http://www.linuxidc.com/Linux/2014-11/108791.htm 相关类Executor,Executors,AbstractExecutorService,Ex ... 
- 《java.util.concurrent 包源码阅读》 结束语
		<java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ... 
- J.U.C FutureTask之源码解析
		通过直接继承Thread, 实现Runnable接口来创建线程.但这两种方式都有一种缺陷:在执行完任务之后无法获得执行结果. 如果需要获得执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果, ... 
- 线程池ThreadPoolExecutor源码解读研究(JDK1.8)
		一.什么是线程池 为什么要使用线程池?在多线程并发开发中,线程的数量较多,且每个线程执行一定的时间后就结束了,下一个线程任务到来还需要重新创建线程,这样线程数量特别庞大的时候,频繁的创建线程和销毁线程 ... 
- 从源码看JDK提供的线程池(ThreadPoolExecutor)
		一丶什么是线程池 (1)博主在听到线程池三个字的时候第一个想法就是数据库连接池,回忆一下,我们在学JavaWeb的时候怎么理解数据库连接池的,数据库创建连接和关闭连接是一个比较耗费资源的事情,对于那些 ... 
随机推荐
- 1、Ext.NET 1.7官方示例笔记-事件
			官网参考地址:https://examples1.ext.net/#/Events/DirectEvents/Overview/ 先了解一下“事件” Ext.NET包括3种事件机制 DirectEve ... 
- 解决:500 Internal Privoxy Error
			500 Internal Privoxy Error Privoxy encountered an error while processing your request: Could not loa ... 
- 使用IDEA创建Spring Boot项目
			第一步:根据1.2.3点鼠标哦: 第二步:点击Next 第三步:按红框框选,然后Next 第四步:选个保存路径,然后Next 第五步:点击Finish就大功告成了 
- python中pip添加国内镜像源后显著加速下载
			python中pip添加国内镜像源后显著加速下载 更换pip源到国内镜像,很多国外的库下载非常慢,添加国内镜像后安装下载速度提升非常明显(亲测有些可以由几十kb加速到几MB) pip国内的一些镜像阿里 ... 
- hibernate  createSQLQuery  StringIndexOutOfBoundsException: String index out of range: 0
			有一个sql用union拼接的如下: select id,(**还有很多字段**),'' as NewName from tb1 union select id,(**还有很多字段**),name a ... 
- E203 译码模块(2)
			常用的alu算术运算指令(包括ecall和 ebreak)在regular alu单元处理.regular alu单元为alu单元的一个子单元.regular单元的信息总线共21位,格式如下图所示,其 ... 
- Mysql时区无法识别
			Unable to connect to database. Tried 1 times {:error_message=>“Java::JavaSql::SQLException: The s ... 
- Ubuntu的apt命令详解
			apt-cache和apt-get是apt包的管理工具,他们根据/etc/apt/sources.list里的软件源地址列表搜索目标软件.并通过维护本地软件包列表来安装和卸载软件. 查看本机是否安装软 ... 
- 模板渲染 templates
			目录 一.模板含义 二.模板的组成 三.逻辑控制代码 变量 标签 自定义过滤器 模板继承 一.模板含义 模板虽然是HTML文件,但是Django不是直接把HTML文件返回给用户,而是经过了 模板语言的 ... 
- cf1208G Polygons 欧拉函数
			链接 cf 给你两个正整数\(n\)和\(k\),询问在一个圆上你最少需要几个点构才能造出\(k\)个边数小于等于\(n\)的正多边形 思路 深受迫害,所以写的详细一点,不会请留言. 性质1 考虑加进 ... 
