使用ThreadLocals的Akka和Java库

时间:2012-11-03 14:59:59

标签: java message-queue akka thread-local thread-local-storage

使我无法定期使用Akka(使用Java)是我对使用ThreadLocals的库的一个担忧。

那就是我认为一些Akka Dispatchers可能导致ThreadLocal变量被遗忘或一起丢失。所以显而易见的解决方案是避免使用 ThreadLocals ,但有很多库使用它们:Spring,Wro4j,Log4j等等......

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

根据我的理解,Akka的情况并非如此。

人们如何解决这个问题?

目前我只是避免使用Akka并使用Message Queue(如RabbitMQ或ActiveMQ),但希望使用Akka,因为它涵盖了更广泛的异步问题/解决方案。

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

1 个答案:

答案 0 :(得分: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,因为它们并没有真正融入分布式系统。它们只在清晰划分的部分工作。