FutureTask,ThreadPoolExecutor

FutureTask_UML
FutureTask设计解释
1.正真开启线程是Thread类(构造函数接受Runnable类型的参数),而Thread又继承了Runnable,执行的就是run()方法。
2.Runnable是一个任务体。
3.Callable也是一个任务体。(相较于Runnable能返回结果而已)
3.Future可以视为一个工具类
源码分析
// FutureTask实现了Runnable类,即可作为任务体传递给Thread执行
// 重写run()方法,最终都是执行Callable的call()方法
    public void run() {
            // 虚假代码.....
            Callable<V> c = callable;
            result = c.call();              
    }

// 如果接收Runnable呢,其实就是做了一个适配转换
 public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
 }

// 可以忽略不看,就是封多了一层方法而已
 public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }

// 正在的转换
private static final class RunnableAdapter<T> implements Callable<T> {
        private final Runnable task;
        private final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            // 执行了Runnable方法的run()方法,返回值类型为传入的泛型
            task.run();
            return result;
        }
    }
FutureTask任务状态流转
  1. NEW:当FutureTask被初始创建的时候的状态。
  2. COMPLETING和NORMAL:当任务被执行完毕,FutureTask会将执行结果设置给FutureTask的outcome属性,在设置之前会将FutureTask的状态修改为COMPLETING,在设置之后会将FutureTask的状态修改为NORMAL。
  3. EXCEPTIONAL:当任务在被执行的过程中抛了异常,FutureTask会将异常信息设置给FutureTask的outcome属性,在设置之前会将FutureTask的状态修改为COMPLETING,在设置之后会将FutureTask的状态修改为EXCEPTIONAL。
  4. CANCELLED:当外部想要取消任务,而又不允许当任务正在执行的时候被取消的时候会将FutureTask的状态修改为CANCELLED。
  5. INTERRUPTING和NTERRUPTED:当外部想要取消任务,同时允许当任务正在执行的时候被取消的时候,会先将FutureTask的状态设置为INTERRUPTING,然后设置执行任务的线程的中断标记位,最后将Future的状态设置为INTERRUPTED。
FutureTask的状态流转可能流程
NEW—>COMPLETING—>NORMAL(任务执行正常)。
NEW—>COMPLETING—>EXCEPTIONAL(任务执行异常)。
NEW—>CANCELLED(不允许执行中的取消)。
NEW—>INTERRUPTING—>INTERRUPTED(允许执行中的取消)。
Future相关方法解析
// 返回值 :已完成或者已取消的前提下调用将返回false;true表示取消成功(任务将不再被执行,)。
// 参数:true表示停止正在执行的任务;false表示不打断正在执行的任务,任务可以正常完成;
 boolean cancel(boolean mayInterruptIfRunning);

  // 重点示例:先调用了cancel(参数无论是true/false),这时候再启动线程任务将不被执行
 FutureTask futureTask = new FutureTask(new Runn5());
 futureTask.cancel(true);
 Thread thread = new Thread(futureTask);
 thread.start();

// 其实就是cancel()的返回值
 boolean isCancelled();

// 任务被取消或者已完成,以及发生异常终止,都将返回true
 boolean isDone();

// 线程阻塞获取结果
V get() throws InterruptedException, ExecutionException,CancellationException;

// 线程 阻塞获取结果,传入等待时长,超过等待时长抛出TimeoutException
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, CancellationException,TimeoutException;

ThreadPoolExecutor
ThreadPoolExecutor_UML

按照默认线程池是实现ExecutorService接口的,按照ExecutorService接口定义的行为,我们可以将Runnable或Callable任务提交到线程池让其去被执行,而被提交的Runnable或Callable任务都会被包装成FutureTask,丢到任务队列,由线程池的工作线程去执行。使用线程池不仅可以提高应用的响应时间,还可以避免”java.lang.OutOfMemoryError: unable to create new native thread” 之类的错误。

ExecutorService方法解析
// 提交任务执行,在调用此方法前调用了shutdown()则会报RejectedExecutionException异常
<T> Future<T> submit(Callable<T> task);
// 线程池会停止接受新的任务,但会完成已提交的任务
void shutdown();
// 返回已提交还没执行的线程,对于正在执行的任务一般会调用interrupt方法尝试中断
List<Runnable> shutdownNow();
// 判断是否执行了shutdown或者shutdownNow()方法
boolean isShutdown();
//获取所有任务是否已经结束,当调用shutdown或者shutdownNow方法后,并且所有提交的任务完成后返回为true
boolean isTerminated();
// 阻塞等待所有任务结束,可以设置timeout,如果超时了所有任务还未完成则返回false,反之
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
// 批量提交任务,整个过程为阻塞,是因为内部执行了Future.get(),所有任务都执行完毕后才返回。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
// 和上面方法相同,只是了限定时间
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容