Programming in Scala ch30 (Actor..
时间:2010-09-27
来源:jamesqiu
30.3 原生线程和actor(P612)
actor管理1个或多个原生线程,但使用actor时不用考虑它和原生线程的对应关系。
每个原生线程也被作为一个actor来使用,但不能通过Thread.current来直接获取当前actor的线程,需要使用Actor.self,这在Scala的交互式REPL环境中调试actos时很有用:
scala> import scala.actors.Actor._
scala> self ! "hello"
scala> self.receive { case x => x }
res9: Any = hello
没有消息的情况下调用self.receive { case x=>x }会一直阻塞,但receiveWith超时可退出:
scala> self.receiveWithin(1000) { case x => x } // 等1秒
res0: Any = TIMEOUT
30.4 线程复用以提高性能(P613)
actor在Java线程之上包装实现,实际上每个actor都有其对应的线程。
Java中的线程并没有想象中的轻量,线程需要更多内存,一般可容纳百万级数量objects的JVM仅能容纳上千级别数量的线程。更糟糕的是,线程间的切换常常需要几百乃至上千个CPU时钟周期。如果需要程序尽可能高效,很重要的一点就是要减少线程的创建和线程间的切换。
为了复用线程,Scala提供了receive方法之外的另一选择:react。react和receive用法差不多,不过react处理消息后并无返回值,react处理消息的结果是Nothing类型(其实react处理完消息后是抛异常)。
由于react方法不需要返回,其实现就无需保存当前线程的调用栈,所以当前线程可以被下一个唤醒的actor所使用。该方法很高效,如果程序中所有actor都使用react方法而不是receive方法,只需一个线程就可以处理程序所有的actor(如果计算机是多核CPU,actor就会生成足够多的线程以充分利用CPU所有的核)。
提示:尽可能地使用react来复用线程。
由于react不返回,它处理完消息后还需要进行后续处理。一种常用方法是处理完消息后调用react的上层方法act自身,如:
import actors._, actors.Actor._, java.net._
object NameResolver extends Actor { // 得到域名对应的ip
def act() {
react {
case (name: String, actor: Actor) => actor ! getIp(name); act()
case "EXIT" => println("Name resolver exiting.")
case msg => println("Unhandled message: " + msg); act()
}
}
def getIp(name: String): Option[InetAddress] = {
try { Some(InetAddress.getByName(name))
} catch { case _: UnknownHostException => None }
}
}
// 调用:
scala> NameResolver.start()
scala> NameResolver ! ("www.scala-lang.org", self)
scala> self.receiveWithin(0) { case x => x }
res3: Any = Some(www.scala-lang.org/128.178.154.159)
scala> NameResolver ! ("wwwwww.scala-lang.org", self)
scala> self.receiveWithin(0) { case x => x }
res5: Any = None
这种方法很常用,故actors.Actor中已经提供了loop函数来完成这个工作,loop循环执行之后程序块{..}的代码。上面的NameResolver可以改写如下:
def act() {
loop {
react {
case (name: String, actor: Actor) => actor ! getIp(name)
case msg => println("Unhandled message: " + msg)
}
}
}
热门阅读
- office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
- 如何安装mysql8.0
阅读:31
- Word快速设置标题样式步骤详解
阅读:28
- 20+道必知必会的Vue面试题(附答案解析)
阅读:37
- HTML如何制作表单
阅读:22
- 百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
- ET文件格式和XLS格式文件之间如何转化?
阅读:24
- react和vue的区别及优缺点是什么
阅读:121
- 支付宝人脸识别如何关闭?
阅读:21
- 腾讯微云怎么修改照片或视频备份路径?
阅读:28