java多线程——FutureTask的用法

  • A+
所属分类:Java 多线程

之前介绍了线程池相关的对象,Runable Callable与Future,下面介绍FutureTask的作用,它的特性是怎样的呢?

FutureTask特点

先看FutureTask的类图:

java多线程——FutureTask的用法

从上图我们可以看到FutureTask实现了RunableFuture接口,同时RunableFuture又继承Future,Runable接口,也就是说FutureTask具备Runbale的run方法执行异步任务,也可以像Future一样能够控制任务的执行

内部成员变量

java多线程——FutureTask的用法

状态信息分为:

NEW:任务新建; COMPLETING:任务即将完成;NORMAL:正常执行结束; EXCEPTIONAL:任务出现异常

CANCELLED:任务取消,INTERRUPTING:任务中断中 ,INTERRUPTED:任务已中断。

状态转换的序列:

NEW -> COMPLETING -> NORMALNEW -> COMPLETING -> EXCEPTIONALNEW -> CANCELLEDNEW -> INTERRUPTING -> INTERRUPTED

其他变量:

java多线程——FutureTask的用法

核心方法

构造方法:FutureTask(Callable<V> callable)和FutureTask(Runnable runnable, V result),接收callable和Runable,和结果result。

run()

java多线程——FutureTask的用法

主要的流程:

如果当前状态不是NEW,或者调用CAS方法,判断RUNNER为null的话,都直接返回读取Callable 变量然后校验状态,执行call方法。如果执行call()的过程中发生异常,就调用设置异常信息,如果执行成功,则将执行set(result),设置结果如果业务逻辑异常,则调用setException方法将异常对象赋给outcome,并且更新state值最后会将runner设置为null,判断状态信息如果是INTERRUPTING,则表示正在被中断,交出线程执行权,让其他线程执行get()和get(long timeout, TimeUnit unit)

java多线程——FutureTask的用法

这个跟future的含义一致,get()阻塞等待,get(long timeout, TimeUnit unit),阻塞特定的时间。其中主要分析下awaitDone(false, 0L)这个方法的具体逻辑:

java多线程——FutureTask的用法

这是一个循环,如果当前线程被打断那么抛出异常,如果没有则取出状态信息s,如果s > COMPLETING,表示任务已经执行结束,或者出现异常结束,那么将等待节点中队列设置为null。s==COMPLETING 那么让出线程执行如果等待节点q为null,则闯将,并且将它插入到等待队列中,之后判断timed是否等待实现,如果是则计算具体时间执行LockSupport.parkNanos(this, nanos),等待具体的时间,否则LockSupport.parkNanos(this),进入一直阻塞状态。cancel(boolean mayInterruptIfRunning)1.如果子任务还没有执行,那么该任务执行停止,如果子任务已经执行,且mayInterruptIfRunning=true

,那么执行子任务的线程也会被中断

finishCompletion()

不管是什么样的任务,无论取消还是其他,最后都会调用finishCompletion()方法具体应用实例:

一个能够有控制的异步任务:

java多线程——FutureTask的用法

以上总结:

FutureTask作为一个可以控制的异步任务的存在,是对Runable实现一种继承和扩展,再这里我们熟悉它的一些用法和应用场景,对内部方法进行学习。多接口的继承是我们日后开发设计中需要掌握的

ps:如果您觉得对文章对您有帮助,欢迎收藏和关注,这将是对我最大肯定

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: