9

やあ、

私は新しいfuturesライブラリでScala2.10を使用しており、無限ループをテストするためのコードを記述しようとしています。を使用しscala.concurrent.Futureて、別のスレッドでループを使用してコードを実行します。次に、テストを行うために少し待ってから、別のスレッド/将来を強制終了したいと思います。私は見てきましたAwait.resultが、それは実際には未来を殺しません。新しいScala2.10先物をタイムアウトまたは強制終了する方法はありますか?

この単純な部分のためだけに、Akkaなどの外部依存関係を追加する必要はありません。

4

3 に答える 3

7

家で試さないでください。

import scala.concurrent._
import scala.concurrent.duration._

class MyCustomExecutionContext extends AnyRef with ExecutionContext {
  import ExecutionContext.Implicits.global
  @volatile var lastThread: Option[Thread] = None
  override def execute(runnable: Runnable): Unit = {
    ExecutionContext.Implicits.global.execute(new Runnable() {
      override def run() {
        lastThread = Some(Thread.currentThread)
        runnable.run()
      }
    })
  }
  override def reportFailure(t: Throwable): Unit = ???
}    

implicit val exec = new MyCustomExecutionContext()
val f = future[Int]{ do{}while(true); 1 }
try {
  Await.result(f, 10 seconds) // 100% cpu here
} catch {
  case e: TimeoutException => 
    println("Stopping...")
    exec.lastThread.getOrElse(throw new RuntimeException("Not started"))
      .stop() // 0% cpu here
}
于 2013-01-22T01:23:44.043 に答える
2

いいえ-ループがチェックするフラグを追加する必要があります。フラグが設定されている場合は、ループを停止します。フラグが少なくともであることを確認してくださいvolatile

Java同時実行の実際、p135-137を参照してください。

于 2013-01-22T01:22:24.190 に答える
1

私は同様の問題を抱えており、次のノンブロッキングの将来の操作を書きました:

class TerminationToken(var isTerminated: Boolean)
object TerminationToken { def apply() = new TerminationToken(false) }

 implicit class FutureOps[T](future: Future[Option[T]]) {
 def terminate(timeout: FiniteDuration, token: TerminationToken): Future[Option[T]] = {
   val timeoutFuture = after[Option[T]](timeout, using = context.system.scheduler) {
     Future[Option[T]] { token.isTerminated = true; None } }
          Future.firstCompletedOf[Option[T]](Seq (future recover { case _ => None }, timeoutFuture))
     }
   }

次に、オプションを返すfutureを作成し、それに.terminate(timeout、token)を使用します。

于 2013-11-28T17:20:27.640 に答える