Future的isCompleted方法如何实现?附代码示例解析
嘿,关于Scala里Future的isCompleted方法,我来给你拆解一下它的实现逻辑~
先看你给出的代码示例,这段代码创建了一个读取文件内容的Future,然后两次检查它的完成状态:
val sbtFile: Future[String] = Future{ val f = Source.fromFile("build.sbt") try f.getLines.mkString("\n") finally f.close() } println(s"status: ${sbtFile.isCompleted}") Thread.sleep(250) println(s"status: ${sbtFile.isCompleted}") println(s"value: ${sbtFile.value}")
第一次打印isCompleted大概率会返回false,因为Future的异步任务可能还没执行完;而sleep 250毫秒后,任务基本完成,第二次就会返回true,value也会返回包含结果的Some对象。
核心定义:抽象方法的子类实现
在Scala的Future trait中,isCompleted确实是一个抽象方法:
abstract def isCompleted: Boolean
它的具体实现是由Future的实际子类来完成的——我们平时用Future{...}创建的实例,背后其实是Promise.DefaultPromise这个类(Scala标准库默认的Promise实现)。
DefaultPromise中的isCompleted实现逻辑
DefaultPromise内部维护了一个原子状态变量,用来记录当前Future的状态:
- 初始状态是
Pending(未完成) - 当任务成功完成时,状态变为
Success(result) - 当任务抛出异常时,状态变为
Failure(exception)
isCompleted方法的逻辑非常直接:它会检查这个原子状态是否已经脱离了Pending状态——只要是Success或者Failure,就返回true,否则返回false。而且因为用了原子操作,这个检查是线程安全的,不用担心多线程环境下的竞态问题。
关于Future伴生对象的never
你提到的Future伴生对象里的never,是一个特殊的Future实例:它的状态永远是Pending,永远不会被更新。所以它的isCompleted方法会永远返回false,适合用来表示那些永远不会完成的异步任务场景。
最后补充一点:isCompleted是一个非阻塞的方法,它只是即时检查当前的状态,不会等待Future完成——这也是为什么你的示例里需要sleep才能看到状态变化的原因。
内容的提问来源于stack exchange,提问作者Mandroid

