【发布时间】:2015-01-14 03:19:59
【问题描述】:
当我们有创建资源的方法时,有时只需要等待指定的持续时间。例如,我们要等待 10 秒才能连接到数据库。
我尝试使用 future 和 Await.result 来获得它。不幸的是, Await.result 在指定时间后抛出异常,但不会杀死正在进行的未来。因此,在超时之后,我们以 TimeoutException 告终,但如果未来最终完成,我们将无法关闭返回的结果。 示例:
import java.io.Closeable
import java.util.concurrent.TimeoutException
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
import scala.concurrent.future
object Test {
object ConnectionManager {
class Connection extends Closeable {
println("Connected")
override def close = println("DB closed")
}
def connect = {
println("Connecting to DB...")
Thread.sleep(1000 * 7)
new Connection
}
}
def main(args: Array[String]): Unit = {
val f = future {
ConnectionManager.connect
}
try {
val result = Await.result(f, 5 seconds)
result.close
} catch {
case e: TimeoutException => println("Connection timeout")
}
Thread.sleep(10 * 1000)
println("Finished")
}
}
结果是:
正在连接数据库...
连接超时
已连接
完成
所以连接被创建但从未关闭
【问题讨论】:
-
如果等待结果超时,为什么还要使用 Future?基本上真正的超时会抛出异常并且永远不会创建连接。
-
我需要自己提供时间。不是通过外部库。数据库连接只是一个例子。其他示例包括获取网络资源和创建 InputStream。如果连接时间过长,我们希望使此类操作超时。