13

使我无法定期使用 Akka(在 Java 中)的原因是我对使用 ThreadLocals 的库感到担忧。

那就是我认为一些 Akka Dispatchers 可能会导致 ThreadLocal 变量被抛在后面,或者一起丢失。因此,显而易见的解决方案是避免使用ThreadLocals,但是有很多库使用它们:Spring、Wro4j、Log4j 等...

ThreadLocals 通常在 Servlet 容器中工作正常。那是因为即使容器有线程池,请求主要是一个同步生命周期,因此通常在请求结束时,像 Spring 和 Wro4J 之类的东西会清理那里的 threadlocals。像 Tomcat 这样的一些容器甚至可以监控线程本地泄漏。

据我了解,Akka 并非如此。

人们如何绕过这个问题?

现在我只是避免使用 Akka 并使用消息队列(如 RabbitMQ 或 ActiveMQ),但我想使用 Akka,因为它涵盖了更广泛的异步问题/解决方案。

我也认为 Netty 有类似的问题,但我相信 Netty 提供了某种 Channel Context 对象,您可以使用它来代替 ThreadLocal,并且理论上一些库可能知道使用它而不是 ThreadLocal。

4

1 回答 1

3

解决它的最简单方法是划定 ThreadLocals 的使用,因此您可以这样创建一个方法:

def withSecurityContext[T](thunk: => T)(implicit secCtx: SecurityContextFetcher): T = {
  val old = threadLocalSecurityContext.get
  threadLocalSecurityContext.set(secCtx.fetch)
  try thunk finally threadLocalSecurityContext.set(old)
}

然后在你的演员或其他内部:

class MyActor extends Actor {
    def receive = {
      case "foo" => withSecurityContext { beAwesome() }
    }
}

不过总的来说,我会避免使用 ThreadLocals,因为它们并没有真正融入分布式系统。它们只在明确划分的部分工作。

于 2012-11-04T16:04:14.307 回答