嗨,
我试图编写一些代码来测试无限循环 . 我使用 scala.concurrent.Future 在一个单独的线程中使用循环运行代码 . 然后我想等一会儿做一些测试,然后杀死单独的线程/未来 . 我看过 Await.result 但实际上并没有杀死未来 . 有没有办法超时或杀死新的Scala 2.10期货?
scala.concurrent.Future
Await.result
我宁愿不必为这个简单的部分添加外部依赖项,如Akka .
不要在家尝试 .
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 }
不 - 您必须添加循环检查的标志 . 如果设置了标志,请停止循环 . 确保该标志至少为 volatile .
volatile
见Java Concurrency in Practice,第135-137页 .
我遇到了类似的问题并编写了以下非阻塞的未来操作:
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)
3 回答
不要在家尝试 .
不 - 您必须添加循环检查的标志 . 如果设置了标志,请停止循环 . 确保该标志至少为
volatile
.见Java Concurrency in Practice,第135-137页 .
我遇到了类似的问题并编写了以下非阻塞的未来操作:
然后创建一个返回选项的future,并在其上使用.terminate(timeout,token)