关于java:java的FutureTask类的用法介绍

33次阅读

共计 1999 个字符,预计需要花费 5 分钟才能阅读完成。

java 的 FutureTask 类用法

1.FutrueTask 概念

FutureTask 一个可勾销的异步计算,FutureTask 实现了 Future 的根本办法,提空 start cancel 操作,能够查问计算是否曾经实现,并且能够获取计算的后果。后果只能够在计算实现之后获取,get 办法会阻塞当计算没有实现的时候,一旦计算曾经实现,那么计算就不能再次启动或是勾销。

一个 FutureTask 能够用来包装一个 Callable 或是一个 runnable 对象。因为 FurtureTask 实现了 Runnable 办法,所以一个 FutureTask 能够提交 (submit) 给一个 Excutor 执行(excution).

2.FutureTask 应用场景

FutureTask 可用于异步获取执行后果或勾销执行工作的场景。通过传入 Runnable 或者 Callable 的工作给 FutureTask,间接调用其 run 办法或者放入线程池执行,之后能够在内部通过 FutureTask 的 get 办法异步获取执行后果,因而,FutureTask 非常适合用于耗时的计算,主线程能够在实现本人的工作后,再去获取后果。另外,FutureTask 还能够确保即便调用了屡次 run 办法,它都只会执行一次 Runnable 或者 Callable 工作,或者通过 cancel 勾销 FutureTask 的执行等。

2.1 FutureTask 执行多任务计算场景

利用 FutureTask 和 ExecutorService,能够用多线程的形式提交计算工作,主线程继续执行其余工作,当主线程须要子线程的计算结果时,在异步获取子线程的执行后果。

View Code
2.2 FutureTask 在高并发下确保工作只执行一次

在很多高并发的环境下,往往咱们只须要某些工作只执行一次。这种应用情景 FutureTask 的个性恰能胜任。举一个例子,假如有一个带 key 的连接池,当 key 存在时,即间接返回 key 对应的对象;当 key 不存在时,则创立连贯。对于这样的利用场景,通常采纳的办法为应用一个 Map 对象来存储 key 和连接池对应的对应关系,典型的代码如上面所示:

View Code
在下面的例子中,咱们通过加锁确保高并发环境下的线程平安,也确保了 connection 只创立一次,然而确就义了性能。改用 ConcurrentHash 的状况下,简直能够防止加锁的操作,性能大大提高,然而在高并发的状况下有可能呈现 Connection 被创立屡次的景象。这时最须要解决的问题就是当 key 不存在时,创立 Connection 的动作能放在 connectionPool 之后执行,这正是 FutureTask 发挥作用的机会

FutureTask 可用于异步获取执行后果或勾销执行工作的场景。通过传入 Runnable 或者 Callable 的工作给 FutureTask,间接调用其 run 办法或者放入线程池执行,之后能够在内部通过 FutureTask 的 get 办法异步获取执行后果,因而,FutureTask 非常适合用于耗时的计算,主线程能够在实现本人的工作后,再去获取后果。另外,FutureTask 还能够确保即便调用了屡次 run 办法,它都只会执行一次 Runnable 或者 Callable 工作,或者通过 cancel 勾销 FutureTask 的执行等。

实现剖析

在剖析实现前,咱们先想下如果让咱们实现一个相似 FutureTask 的性能,咱们会如何做?因为须要获取执行后果,须要一个 Object 对象来存执行后果。工作执行工夫不可控性,咱们须要一个变量示意执行状态。其余线程会调用 get 办法获取后果,在没达到超时的时候须要将线程阻塞或挂起。

因而须要一个队列相似的构造存储期待该后果的线程信息,这样在工作执行线程实现后就能够唤醒 XM 返佣 https://www.kaifx.cn/broker/x…,失去后果。FutureTask 的理论实现也是相似的逻辑,具体如下。

首先看下 FutureTask 的次要成员变量如下:

1
2
3
4
5
6
7
8

//futureTask 执行状态
private volatile int state;
// 具体的执行工作,会在 run 办法中抵用 callable.call()
private Callable<V> callable;
// 执行后果
private Object outcome;
// 获取后果的期待线程节点
private volatile WaitNode waiters;

对于执行状态,在源码中曾经有了十分清晰的解释,这里我只是贴出源码,不在进行阐明,具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

/**

  • Possible state transitions:
  • NEW -> COMPLETING -> NORMAL
  • NEW -> COMPLETING -> EXCEPTIONAL
  • NEW -> CANCELLED
  • NEW -> INTERRUPTING -> INTERRUPTED
正文完
 0