Java ThreadLocal 介绍


最早接触 ThreadLocal 这个东东,还是在学 Hibernate 的时候,当时看 ThreadLocal 没 明白是干什么的,后来在网上查才明白 ThreadLocal 的用途,ThreadLocal 其实蛮有用的, 总结一下具体的原理及用法。 虽然支持线程局部变量早就是许多线程工具,但 Java Threads API 的最初设计却没有这项 有用的功能。而且,最初的实现也相当低效。ThreadLocal 极少受到关注,但对简化线程安 全并发程序的开发来说,它却是很方便的。 ThreadLocal 要解决的是什么问题呢? 一个本来应该线程安全的类,里面有一个线程不安全的变量,这样这个类也就线程不安全 了,那应该怎么办呢?我们如果能够把这个变量和每个线程绑定, 也就是每一个线程拥有 这个变量的副本,那么整个对象就成为线程安全的了。一个解决方案就是使用一个 Map,key 对应于当前的线程,value 对应于那个 变量,这样我们就可以轻易的获取到当前 线程的那个变量的副本了,ThreadLocal 就是这个东东。 我们不妨写写大致的代码: 当然 java 的 ThreadLocal 实现的总体思路也大致如此。 我们看看 jdk 提供的 api 文档: T get() 返回此线程局部变量的当前线程副本中的值 ,如果变量没有用于当前线程的值,则先 将其初始化为调用 initialValue() 方法返回的值 protected T initialValue() 返回此线程局部变量的当前线程的 “初始值 ”。 void remove() 移除此线程局部变量当前线程的值。 void set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值。 我们看 jdk 文档提供了一个例子 : 这个例子我看的时候没看懂 ,其实是有错误的 return uniqueId.get();, 应该是 return uniqueNum.get(); 我用的是中文翻译过来的 jdk api 1.6.0, 不知道 大家的 jdk 帮助文档有没有 这个问题 . 我们看看 Hibernate 官方文档提供的一个通过 ThreadLocal 维护 Session 的例子 : 其它适合使用 ThreadLocal 但用池却不能成为很好的替代技术的应用程序包括存储或累积 每线程上下文信息以备稍后检索之用这样的应用程序。例如,假设您想创建一个用于管理 多线程应用程 序调试信息的工具。您可以用 DebugLogger 类作为线程局部容器来累积调试 信息。在一个工作单元的开头,您清空容器,而当一个错误出现时,您查询该容器以检索 这个工作单元迄今为止生成的所有调试信 息。 用 ThreadLocal 管理每线程调试日志 在您的代码中,您可以调用 DebugLogger.put() 来保存您的程序正在做什么的信息,而且, 稍后如果有必要(例如发生了一个错误),您能够容易地检索与某个特定线程相关的调试 信息。 与简单地把所有信息转储到一个日志文件,然后努力找出哪个日志记录来自哪个线 程(还要担心线程争用日志纪录对象)相比,这种技术简便得多,也有效得多。 ThreadLocal 在基于 servlet 的应用程序或工作单元是一个整体请求的任何多线程应用程序 服务器中也是很有用的,因为在处理请求的整个过程中将要用到单个线程。您可以通过每 线程单子技术 用 ThreadLocal 变量来存储各种每请求(per-request )上下文信息。 ThreadLocal 能带来很多好处。它常常是把有状态类描绘成线程安全的,或者封装非线程 安全类以使它们能够在多线程环境中安全地使用的最容易的方式。使用 ThreadLocal 使我 们可以绕过为实现线程安全而对何时需要同步进行判断的复杂过程,而且因为它不需要任 何同步,所以也改善了可伸缩性。除简单之外,用 ThreadLocal 存储每线程单子或每线程 上下文信息在归档方面还有一个颇有价值好处 :通过使用 ThreadLocal ,存储在 ThreadLocal 中的对象都是 不被线程共享的是清晰的,从而简化了判断一个类是否线程安全的工作。 当然 ThreadLocal 并不能替代同步机制,两者面向的问题领域不同。同步机制是为了同 步多个线程对相同资源的并发访问,是为了多个线程之间进行通信 的有效方式;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变 量),这样当然不需要对多个线程进行同步了。所 以,如果你需要进行多个线程之间进行 通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用 ThreadLocal , 这将极大地简化你的程 序,使程序更加易读、简洁。
还剩4页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 3 人已下载

下载pdf

pdf贡献者

nickelen

贡献于2011-12-29

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf