首页 > 解决方案 > 从外部输入改变值的流

问题描述

我想要做

while(isRunning) {
   // do something
}

并且能够从另一个线程做isRunning = false和上面的循环停止。

但是,我想以一种更类似于 scala 的方式来做到这一点。

我尝试过的一种方法是:

object Watcher {
  var run: Boolean = true
  def getIsRunning: Stream[Boolean] = {
    { Thread.sleep(1000); run } #:: getIsRunning
  }
}

然后我打算这样做:

Watcher.getIsRunning.takeWhile { isRunning => 
  if (isRunning) { 
     println("I am running")
  } else {
     println("I am not running")
  }
  isRunning
}

但它(现在显然)不起作用,因为takeWhile返回另一个流并且不像while循环那样重新评估run每次的值。

有没有办法做我想做的事?

标签: scala

解决方案


我不确定您所说的“现在显然”指的是什么……对我来说,为什么您认为这不起作用(实际上,我认为应该起作用)对我来说并不明显。我不太明白为什么它需要如此复杂(以及while循环有什么问题),但在功能上,它似乎没有任何问题......

另一种(可以说,甚至更“类似 scala”)的方法是使用期货:

   def whileRunning(f: => Unit): Future[Unit] = Future(f).flatMap {
     case _ if isRunning => whileRunning(f)
     case _ => Future.successful
   }         

现在,你可以做whileRunning(doWork)......而且它没有阻塞,所以你实际上可以isRunning=true稍后再做(确保它是@volatile)。


推荐阅读