如何在Scala中的线程之间进行通信?

时间:2013-08-29 16:18:53

标签: scala

我在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()

1 个答案:

答案 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