Mic*_*ael 53 multithreading scala future
Java Future有一个cancel方法,它可以中断运行Future任务的线程.例如,如果我将一个可中断的阻塞调用包装在一个Java Future我可以稍后中断它.
Scala Future没有提供任何cancel方法.假设我在一个中包含一个可中断的阻塞调用Scala Future.我怎么能打断它?
axe*_*l22 30
这还不是FutureAPI 的一部分,但可能会在未来作为扩展添加.
作为一种解决方法,您可以使用firstCompletedOf包装2期货 - 您要取消的未来以及来自自定义的未来Promise.然后你可以通过失败承诺取消这样创建的未来:
def cancellable[T](f: Future[T])(customCode: => Unit): (() => Unit, Future[T]) = {
val p = Promise[T]
val first = Future firstCompletedOf Seq(p.future, f)
val cancellation: () => Unit = {
() =>
first onFailure { case e => customCode}
p failure new Exception
}
(cancellation, first)
}
Run Code Online (Sandbox Code Playgroud)
现在你可以在任何将来调用它来获得"可取消的包装器".用例示例:
val f = callReturningAFuture()
val (cancel, f1) = cancellable(f) {
cancelTheCallReturningAFuture()
}
// somewhere else in code
if (condition) cancel() else println(Await.result(f1))
Run Code Online (Sandbox Code Playgroud)
编辑:
有关取消的详细讨论,请参阅Scala中的学习并发编程一书中的第4章.
我没有对此进行测试,但这扩展了PabloFranciscoPérezHidalgo的答案.而不是阻止等待java Future,我们使用中间Promise代替.
import java.util.concurrent.{Callable, FutureTask}
import scala.concurrent.{ExecutionContext, Promise}
import scala.util.Try
class Cancellable[T](executionContext: ExecutionContext, todo: => T) {
private val promise = Promise[T]()
def future = promise.future
private val jf: FutureTask[T] = new FutureTask[T](
new Callable[T] {
override def call(): T = todo
}
) {
override def done() = promise.complete(Try(get()))
}
def cancel(): Unit = jf.cancel(true)
executionContext.execute(jf)
}
object Cancellable {
def apply[T](todo: => T)(implicit executionContext: ExecutionContext): Cancellable[T] =
new Cancellable[T](executionContext, todo)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16085 次 |
| 最近记录: |