Reputation: 1250
I want to do
while(isRunning) {
// do something
}
And be able from another thread to do isRunning = false
and the above loop to stop.
However, I would like to do that in a more scala-like way.
One approach that I tried is :
object Watcher {
var run: Boolean = true
def getIsRunning: Stream[Boolean] = {
{ Thread.sleep(1000); run } #:: getIsRunning
}
}
And then I was going to do:
Watcher.getIsRunning.takeWhile { isRunning =>
if (isRunning) {
println("I am running")
} else {
println("I am not running")
}
isRunning
}
But it ( now obviously ) does not work because takeWhile
return another stream and does not behave like a while
loop which re-evaluate the value of run
every time.
Is there a way to do what I want?
Upvotes: 1
Views: 39
Reputation: 40510
I am not sure what you are referring to by "now obviously" ... it's not obvious to me why you think this should not work (in fact, I think, it should). I don't quite see why it needs to be so complicated (and what's wrong with a while loop), but functionally, there doesn't seem anything wrong with it ...
Another (arguably, even more "scala-like") way to do it, is using futures:
def whileRunning(f: => Unit): Future[Unit] = Future(f).flatMap {
case _ if isRunning => whileRunning(f)
case _ => Future.successful
}
Now, you can do whileRunning(doWork)
... and it's not blocking, so you can actually do isRunning=true
some time later (make sure it's @volatile
).
Upvotes: 3