这将使用FixedThreadPool(以及其内部任务队列):
import scala.concurrent._ trait Actor[T] { implicit val context = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(1)) def receive: T => Unit def !(m: T) = Future { receive(m) } }
大小为1的FixedThreadPool可以保证顺序性。当然,如果您需要100500个动态创建的actor,它不是管理线程的最佳方式,但如果您需要每个应用程序的一些固定数量的actor来实现您的协议,那就没问题了。
用法:
class Ping(pong: => Actor[Int]) extends Actor[Int] { def receive = { case m: Int => println(m) if (m > 0) pong ! (m - 1) } } object System { lazy val ping: Actor[Int] = new Ping(pong) //be careful with lazy vals mutual links between different systems (objects); that's why people prefer ActorRef lazy val pong: Actor[Int] = new Ping(ping) } System.ping ! 5
结果:
import scala.concurrent._ defined trait Actor defined class Ping defined object System res17: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@6be61f2c 5 4 3 2 1 0 scala> System.ping ! 5; System.ping ! 7 5 7 4 6 3 5 2 res19: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@54b053b1 4 1 3 0 2 1 0
这个实现使用两个Java线程,因此它比没有并行化的计数快“两倍”。