我在Scala中有一个带有一些方法的类,每个方法都有一个执行时间,例如methodA
需要10秒而methodB
需要5秒。并且每个方法都异步调用。当我调用methodB
时,它应该取消运行另一个方法的线程。我先调用methodA,2秒后调用methodB。这个问题的最佳解决方案是什么?
def methodA()={
async{
// a job that takes 10 seconds
}
}
def methodB()={
async{
// other methods should stop their job
// a job that takes 5 second
}
}
def async[T](fn: => Unit): Unit = scala.actors.Actor.actor {
fn
}
.....
methodA()
methodB()
答案 0 :(得分:1)
这是一个想法,基于您的方法主动检查它是否仍应运行或取消的假设:
import concurrent.{ExecutionContext, Future, Promise, blocking, future, promise}
case class Cancelled() extends RuntimeException
object Job {
def apply[A](fun: (() => Boolean) => A)(implicit ctx: ExecutionContext): Job[A] =
new Job[A] {
private val p = promise[A]
def result = p.future
def cancel(): Unit = p.tryFailure(Cancelled())
p tryCompleteWith future {
fun(() => !p.isCompleted)
}
}
}
trait Job[A] {
def result: Future[A]
def cancel(): Unit
}
所以Job
体现了未来和cancel()
方法。您的示例可能与此类似:
import ExecutionContext.Implicits.global
val a = Job { active =>
for (i <- 1 to 100 if active()) {
blocking {
Thread.sleep(1000) // doing actual heavy work here
println(s"A $i")
}
}
}
val b = Job { active =>
for (i <- 1 to 20 if active()) {
blocking {
Thread.sleep(1000) // doing actual heavy work here
println(s"B $i")
}
}
println("Goodbye A...")
a.cancel()
}
我还看到了一个harsh variant而非Thread.interrupt
。