【问题标题】:Akka and Java libraries that use ThreadLocals使用 ThreadLocals 的 Akka 和 Java 库
【发布时间】:2012-10-24 00:03:50
【问题描述】:

让我无法经常使用 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。

【问题讨论】:

  • 您对 ThreadLocals 有什么顾虑?你能详细说明一下吗?
  • 假设 Spring 将事务绑定到线程,因为我在 Actor 中进行了某种 JDBC 操作,然后 Akka 基本上挂起该线程并将其交给不同的 Actor……你可能会觉得有些奇怪行为......或者更糟糕的是,交易可能永远不会关闭。再比如Log4J和logback的MDC:groups.google.com/d/msg/akka-user/f5YDBKVExmQ/_mOOuQu2SXcJ
  • @AlexObjelean for Wro4j 它让一个问题,因为它在请求线程中,我不认为你有它,所以它继承到其他线程(虽然我在尝试让你的与 Netty 一起工作的库我最终只是自己做了资产管道,避免了 wro4j 的上下文对象)。
  • 我认为你不必太担心 ThreadLocal 本身,而不是 ThreadLocal 的草率使用:old.nabble.com/…

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


【解决方案1】:

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

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

然后在你的 Actor 或其他内部:

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

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

【讨论】:

  • 您认为 Akka 是否值得像 Tomcat 那样支持一些 ThreadLocal 泄漏检测(可能在 Akka 关闭时)?也许我可以做的一个小项目(移植 Tomcat 的检测)有助于减轻我的恐惧 :)
  • Akka 是开源的,如果你想解决这个问题并提交 PullRequest,我很乐意考虑包含它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 2020-01-05
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
相关资源
最近更新 更多