`
wydyyhwzx
  • 浏览: 8985 次
社区版块
存档分类
最新评论

ThreadLocal使用

阅读更多

       ThreadLocal提供了线程局部 (thread-local) 变量,访问某个变量(通过其 getset 方法)的每个线程都有自己的局部变量(变量值的副本),它独立于变量的初始化副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。ThreadLocal 实例通常是类中的 private static 字段,每个线程都保持对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。

 

 

     ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本,由于Key值不可重复,每一个“线程对象”对应线程的“变量副本”,而到达了线程安全。

 

      protected  T initialValue()返回该线程局部变量的当前线程的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的,ThreadLocal中的缺省实现直接返回一个null。线程第一次使用

get()

方法访问变量时将调用此方法,但如果线程之前调用了

set(T)

方法,则不会对该线程再调用

initialValue

方法。通常,此方法对每个线程最多调用一次,但如果在调用

get()

后又调用了

remove()

,则可能再次调用此方法。

线程同步机制比较

       ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal

       当然ThreadLocal并不能替代同步机制,两者面向的问题领域不同。同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;而ThreadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变量),这样当然不需要对多个线程进行同步了。所以,如果你需要进行多个线程之间进行通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用ThreadLocal,这将极大地简化你的程序,使程序更加易读、简洁。

       概括起来说,对于多线程资源共享的问题,同步机制采用了以时间换空间的方式,而ThreadLocal采用了以空间换时间的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

 

 

       ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics