Как отменить будущее в Scala?
Java Future и cancel метод, который может прервать поток, который запускает Future задач. Например, если я оберну прерываемый блокировка вызова в Java Future Я могу прервать его позже.
Scala Future не дает cancel метод. Предположим, я оберну прерываемый блокировка вызова в Scala Future. Как я могу прервать его?
4 ответов:
Это еще не часть
FutureС API, но может быть добавлен в качестве расширения в будущем.в качестве обходного пути, вы могли бы использовать
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) }теперь вы можете вызвать это в любом будущем, чтобы получить "отменяемую обертку". Образец вариант использования:
val f = callReturningAFuture() val (cancel, f1) = cancellable(f) { cancelTheCallReturningAFuture() } // somewhere else in code if (condition) cancel() else println(Await.result(f1))EDIT:
подробное обсуждение вопроса об отмене см. В главе 4 в разделе изучение параллельного программирования в Scala книги.
Я не проверял это, но это расширяет ответ Пабло Франсиско Перес Идальго. Вместо того, чтобы блокировать ожидание 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) }
отменяя я думаю, вы хотели бы насильственно прервать
future.нашел этот сегмент кода:https://gist.github.com/viktorklang/5409467
сделал несколько тестов, и кажется, работает хорошо!
наслаждайтесь :)
Я думаю, что можно уменьшить сложность реализаций, предоставляемых с помощью Java 7
Futureинтерфейс и его реализации.
Cancellableможет построить будущее Java, которое будет отменено егоcancelметод. Другое будущее может ждать своего завершения, таким образом, становясь наблюдаемым интерфейсом, который сам по себе неизменен в состоянии:class Cancellable[T](executionContext: ExecutionContext, todo: => T) { private val jf: FutureTask[T] = new FutureTask[T]( new Callable[T] { override def call(): T = todo } ) executionContext.execute(jf) implicit val _: ExecutionContext = executionContext val future: Future[T] = Future { jf.get } def cancel(): Unit = jf.cancel(true) } object Cancellable { def apply[T](todo: => T)(implicit executionContext: ExecutionContext): Cancellable[T] = new Cancellable[T](executionContext, todo) }
Comments