Как безопасно использовать кеши ThreadLocal в Actors? - PullRequest
1 голос
/ 04 ноября 2010

Мое приложение в конечном итоге выполняет много фоновой обработки с помощью Actors, в частности загружает экземпляры Mapper, а затем выполняет над ними некоторую работу.Это очень повторяющееся, и я хотел бы кэшировать некоторые из этих поисков по моему коду Actor.

Я бы обычно использовал для этого ThreadLocal.Однако, поскольку инициализация потока обрабатывается пулом потоков Actor, кажется, что единственное место для инициализации и последующей очистки ThreadLocal будет в PartialFunction актера, которая получает входящие сообщения.

Что я делаю сейчасзаключается в создании другого метода в моем Actor, например:

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

Где метод init обрабатывает очистку ThreadLocal в блоке finally.Мне не нравится этот подход, потому что aroundUpdates существует только для настройки кэша, и он пахнет запахом кода.

Есть ли лучший способ сделать это?

1 Ответ

5 голосов
/ 04 ноября 2010

Вам не нужно использовать локальные потоки : во время одной реакции вы выполняете в одном потоке.Следовательно, вы можете просто использовать обычный var.Более того, поскольку ваши реакции последовательны и подсистема акторов управляет синхронизацией для вас, вы могли бы (если хотите) получить доступ к состоянию из разных реакций:

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
  }

}

Следовательно, локальные потоки не имеют никакого смысла использовать в ваших собственных реакциях!

...