java futuretask_java多线程——FutureTask的用法

FutureTask是Java中实现异步任务控制的重要工具,它继承了Runnable和Future接口,具备运行异步任务并控制其执行的能力。FutureTask的状态包括NEW、COMPLETING、NORMAL、EXCEPTIONAL、CANCELLED和INTERRUPTED,状态转换有明确的序列。构造方法接受Callable或Runnable,run()方法负责任务执行,异常处理和结果设置。get()方法用于阻塞等待任务完成,cancel()方法允许任务取消。finishCompletion()方法在任务结束时被调用,无论任务如何结束。了解FutureTask的这些特性有助于在实际开发中更有效地控制异步任务。

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

FutureTask特点

先看FutureTask的类图:

50ccb2344dd22f75ed9a53a2211a3598.png

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

内部成员变量

9db06418047f276767b9655a164c173b.png

状态信息分为:

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

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

状态转换的序列:

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

其他变量:

12227b58d541f5b1021196c49a9b2294.png

核心方法

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

run():

e113e31d9eec2e8e2242f4480fd02449.png

主要的流程:

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

79c60ab125c89c2e3eb84a4597dd6203.png

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

89058716ef04187a6f75b1a2ae0268bf.png

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

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

finishCompletion()

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

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

c3f6660078d80de2dd133e4bfa708af8.png

以上总结:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值