ThreadLocal实现

时间:2009-09-29 11:42:44

标签: java multithreading thread-local

参考我之前的question,再进一步,

  1. 使用ThreadLocals而不是局部变量
  2. 有什么缺点
  3. 如何实施
  4. 是会话变量ThreadLocals
  5. 是否有更多经常使用的ThreadLocals的例子

3 个答案:

答案 0 :(得分:1)

我不确定我会把它称为缺点但是必须非常小心地正确清理ThreadLocals,因为只要线程存在,除非明确删除,否则放在那里的任何数据都会保留在那里。在使用线程池重用线程的环境中,这尤其麻烦,因此一些垃圾数据可能附加到线程,除非它被正确清理。

ThreadLocals实际上被大量使用 - 主要由框架开发人员使用,因为它们允许在不更改方法签名的情况下将“上下文”附加到用户方法。例如,J2EE中的事务管理是使用ThreadLocals完成的 - 对当前打开事务的引用始终附加到线程,这样当您使用数据库时,您将使用当前打开的事务自动访问它。如果没有ThreadLocal,您需要将这些引用作为方法参数传递。

此类用法还有许多其他示例。我不确定您指的是哪些会话变量,但会话类数据通常会附加到ThreadLocal。

关于实施 - 我不确定。我想我在某个地方读到它是在JVM中实现的相当低的水平,以使性能非常快,因为今天有很多代码使用它。

答案 1 :(得分:0)

  1. 缺点与什么相比?
  2. 作为Map<Thread,Value> - 它实际上是一个附加到线程的地图,但更容易被思考为由线程键入的地图
  3. 没有
  4. ThreadLocals很少使用,应该保持这种状态
  5. 在我看来,应用程序开发人员使用ThreadLocal的唯一原因是他/她需要经常使用具有(相对)高构造成本的非线程安全实用程序对象(例如SimpleDateFormat)。即便如此,这也是一个折腾。

答案 2 :(得分:0)

现实生活中的例子:AMQP消息传递协议允许多个多路复用逻辑连接(称为 channel )共存于一个例如TCP / IP连接。由于某些操作会更改逻辑连接的状态,因此需要将并发消息传递操作建模为并发通道上的操作。当您的并发模型有线程时,您可以通过使用 ThreadLocal get()封装通道访问并使用 initialValue()<打开通道来轻松完成此操作/ em>覆盖。

Spring框架的上下文中,您可以使用适当的target sources透明地使用线程局部bean。