如何在Actors中安全地使用ThreadLocal缓存?

Col*_*lin 1 scala lift

我的应用程序最终通过Actors进行大量后台处理,特别是加载Mapper实例,然后对它们进行一些工作.这是非常重复的,我想在我的Actor代码中缓存一些这些查找.

我通常会使用ThreadLocal.但是,由于线程初始化是由Actor线程池处理的,所以它似乎是唯一一个初始化并随后清除ThreadLocal的地方是在actor的PartialFunction中接收传入的消息.

我现在正在做的是在我的Actor中创建另一个方法,如下所示:

override def aroundUpdates[T](fn: => T) : T = {
  clientCache.init {
    fn
  }
}
Run Code Online (Sandbox Code Playgroud)

init方法处理以清除ThreadLocal的finally块.我不喜欢这种方法,因为aroundUpdates只存在于设置缓存的目的,它闻起来像代码味道.

有一个更好的方法吗?

oxb*_*kes 5

您不需要使用线程本地:在单个响应期间,您在单个线程运行.因此你可以使用正常var.更重要的是,因为您的反应是顺序的,并且actor子系统为您管理同步,您可以(如果您愿意)从不同的反应中访问状态:

def act = loop {
  var state : String = null

  def foo = state = "Hello"
  def bar = { println(state + " World"); state = null }
  def baz = println(state + " Oxbow")
  react {
    case MsgA => foo; bar
    case MsgB => baz
  }

}
Run Code Online (Sandbox Code Playgroud)

因此线程本地人在你自己的反应中没有任何意义!