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

时间:2010-11-04 17:02:17

标签: scala lift

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

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

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

override def aroundUpdates[T](fn: => T) : T = {
  clientCache.init {
    fn
  }
}

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

有更好的方法吗?

1 个答案:

答案 0 :(得分: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
  }

}

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