`
fantaxy025025
  • 浏览: 1311368 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

ThreadLocal的终极问题,拜求解答

阅读更多
下面是几篇不错的文章,论坛还有很多,可以搜一下,讨论的相当火热!
http://blog.csdn.net/happyzhm5/archive/2007/08/09/1734047.aspx
http://www.iteye.com/topic/103804?page=1

我的总结:
    这个问题的起源在研究Hibernate和公司框架时发现的Session release问题,看源码和资料,发现用ThreadLocal比较多。

June 总结:
1. 原理(可以这么想,但内部src不是这样)
通过例子可以看出:ThreadLocal的原理是用一个synchronized Map<Thread, Object>来存储当前线程相关的变量。这样在每一个线程用到obj时,都要取new一个Object。这其实也是很消耗内存的
2. 与new Object的区别
好处1 :区别在于同一个线程用到的都是同一个实例,也就是说本线程在不同的时间,不同的地方(函数等)用到的都是同一个obj,这样的好处是:减少了new 出来的实例obj数量!
好处2 :同一个线程共享一个实例变量,而线程间的实例变量却不同!
        这个好处可以用在Dao操作时,同一个线程得到同一个Session,这样方便于Transaction的整体操作!
好处3 :既然用到obj时不用取new,这样也就少了分配空间、初始化、等开销,这本身相当于一个缓存,只不过这个缓存不是全局的,而是线程局部的!
坏处 :同一个线程共享同一个同一个obj可能会造成混淆!即在线程内,又得注意同步:即当前obj的状态!这个坏处一般破坏不大,因为在同一个线程内,一般不会再开线程,同时,在一个Thread内,是顺序执行,我们非常熟悉,一般不会出错,忘了顺序走过来的值现在的状态(即同一个线程不开子线程 = = 单线程,那么状态可以知道)。多线程的根本问题在于多个线程执行时间、顺序是随即的异步的,状态是不可预测或随机的。
3. synchronized与ThreadLocal
首先说资源共享与竞争,这其实一样,都是多个Thread随机的访问某个变量值,如果不加设置,可能会导致读脏数据、写冲突、等问题。
(1) 需要共享,这个值 不可以设置 不可以改变 那么可以用一个final static解决
(2) 需要共享,这个值可以设置可以改变,那么共享的话会出错!
A 如果需要同步该数据,那么需要用synchronized
B 如果不需要同步数据,那么可以把这个变量变成线程内变量
根据上面分析,synchronized是为了解决同步问题,而同步根本用不着ThreadLocal。
ThreadLocal解决的是同一个线程内的资源共享问题,而synchronized 解决的是多个线程间的资源共享问题,两个问题没有可比性。
4. ThreadLocal根本的用处
从上面ThreadLocal与new Object、与synchronized 的比较,可以知道,ThreadLocal最根本的用处在于:线程内共享数据,即保证当前线程内取到的都是统一对象的引用。
好处:在同一个线程内,完全不相关的两个段代码、函数之间如何共享一个变量呢?通过ThreadLocal可以做到
而且这两段代码之间不用显式的传递参数,降低了耦合。
在java_doc里的描述很到位!如下:
该类提供了线程局部变量。这些变量不同于它们的普通对应物,因为访问一个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
5. 遗留问题:如何释放资源
ThreadLocal中,其它线程无法访问本线程的局部变量!其实也不需要访问,如果需要,那就需要用别的方法!
那么,当前线程结束后,如何才能释放掉现在占用的资源呢?ThreadLocal并没有留下接口,亦不知道其内如是如何做的,但释放资源是个大问题,尤其在保存有重量级资源时,如连接数据库,Socket连接等。

终极问题?如何释放资源
ThreadLocal中,其它线程无法访问本线程的局部变量!其实也不需要访问,如果需要,那就需要用别的方法!
那么,当前线程结束后,如何才能释放掉现在占用的资源呢?ThreadLocal并没有留下接口,亦不知道其内如是如何做的,但释放资源是个大问题,尤其在保存有重量级资源时,如连接数据库,Socket连接等。

Java中ThreadLocal没有留下接口destroy,很是遗憾!
如何释放资源,等待ing ...

------------------------------------------------------------
2009-04-08更新
写这篇文章好久,提问也但没有人来看,不过本人这几天研究发现一个不错的方法,理论可以,还有待实践。
ThreadLocal没有留下释放资源的接口是有原因的:谁知道什么时候线程终止?也就是说,线程的生命周期是不可预期的!而Thread本身没有留下destroy接口,那么ThreadLocal就没办法了!
解决的方法就是用java1.2引入的弱引用:PhantomReference,重写父类ReferenceQueue,促发释放资源的动作!

没时间了,特简写,有需要的朋友可以交流!

分享到:
评论

相关推荐

    ThreadLocal应用示例及理解

    - ThreadLocal不是线程同步机制,不能用来解决多个线程访问共享资源的问题。 - 不要将ThreadLocal用作全局变量,否则可能导致内存泄漏。 - 使用ThreadLocal时,要特别注意线程结束后的清理工作,防止内存泄漏。 - ...

    ThreadLocal

    ThreadLocal通常被用来解决线程共享数据时可能出现的并发问题,避免了使用synchronized关键字进行同步控制的复杂性。 在Java中,ThreadLocal的工作原理是为每个线程创建一个单独的存储空间,每个线程可以独立地读写...

    ThreadLocal中内存泄漏和数据丢失问题的问题浅析及解决方案.docx

    ThreadLocal 中内存泄漏和数据丢失问题的问题浅析及解决方案 ThreadLocal 是 Java 中的一种线程本地存储机制,它可以解决线程之间的数据传递问题。然而,在使用 ThreadLocal 时,可能会出现内存泄漏和数据丢失问题...

    ThreadLocal 内存泄露的实例分析1

    通过添加 `myThreadLocal.remove()`,我们可以确保在每次请求结束后,`ThreadLocal` 不再持有对 `MyCounter` 的引用,从而避免了内存泄漏的问题。 总结:`ThreadLocal` 是一个强大的工具,但在使用时必须谨慎,尤其...

    使用ThreadLocal解决代码分层问题

    javaee开发常见的模式有MVC模式,在C层中常常会再次分层,如:servlet(web层)、service(业务逻辑层)、dao(数据访问层),其中service和dao最容易混在一起,如转...所以,使用ThreadLocal可以解决这样的分层问题。

    ThreadLocal整理.docx

    ThreadLocal 整理 ThreadLocal 是 Java 中... ThreadLocal 是 Java 中的一个重要组件,它能够在每个线程中保持独立的副本,解决 Hash 冲突的机制是通过斐波那契数来实现的,并且提供了扩容机制来避免内存泄漏的问题。

    正确理解ThreadLocal.pdf

    ### 正确理解ThreadLocal:深入解析其工作原理与应用场景 #### 一、ThreadLocal的基本概念 `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每...

    理解ThreadLocal

    理解ThreadLocal 理解ThreadLocal 理解ThreadLocal 理解ThreadLocal

    java事务 - threadlocal

    Java事务和ThreadLocal是两种在Java编程中至关重要的概念,它们分别用于处理多线程环境下的数据一致性问题和提供线程局部变量。 首先,我们来深入理解Java事务。在数据库操作中,事务是一系列操作的集合,这些操作...

    java 简单的ThreadLocal示例

    尽管ThreadLocal在很多场景下都非常有用,但它也有一些潜在的问题需要注意,比如内存泄漏和过度使用可能导致系统资源浪费。因此,理解ThreadLocal的工作原理并谨慎使用是非常重要的。 在提供的"ThreadLocal示例...

    java中ThreadLocal详解

    #### 四、ThreadLocal的内存泄漏问题及其解决方案 尽管使用弱引用来避免内存泄漏,但在某些情况下,仍然可能引起内存泄漏。例如,如果一个`ThreadLocal`实例没有被正确地清理或释放,即使线程已经结束,其`...

    设计模式及ThreadLocal资料

    ThreadLocal的使用需要注意内存泄漏问题,当线程结束但ThreadLocal引用未清除时,可能会导致内存泄露。因此,使用ThreadLocal时,应在适当的时候调用remove()方法,避免内存资源的浪费。 此外,理解线程安全与非...

    ThreadLocal的几种误区

    ThreadLocal是Java编程中一种非常特殊的变量类型,它主要...正确使用ThreadLocal可以提高代码的并发性能,而滥用则可能导致难以预料的问题。因此,在使用ThreadLocal时,需要充分考虑其生命周期管理和线程安全问题。

    ThreadLocal原理及在多层架构中的应用

    综上所述,ThreadLocal是Java多线程编程中的一个重要工具,合理使用能解决许多并发问题,但同时也需要注意其潜在的风险。在多层架构中,ThreadLocal可以有效地提高代码的可读性和性能,但也需要谨慎使用,遵循最佳...

    threadLocal

    2. 并发编程:ThreadLocal是解决并发问题的一种策略,它提供了一种避免共享状态的方式,减少了锁的使用。 3. 内存管理:了解Java的内存模型和垃圾回收机制,才能理解ThreadLocal的内存泄漏风险和弱引用的作用。 4. ...

    使用ThreadLocal管理“session”数据

    ThreadLocal主要用于解决线程间的数据隔离问题,确保各线程拥有自己的变量副本,避免了数据共享带来的并发问题。在Web应用中,特别是对于"session"数据的管理,ThreadLocal可以作为一种有效的解决方案。 1. **什么...

    ThreadLocal简单Demo

    **线程局部变量(ThreadLocal)** 在Java编程中,`ThreadLocal`是一个非常重要的工具类,它用于在多线程环境中提供线程安全的局部变量。`ThreadLocal`并不是一个线程,而是一个线程局部变量的容器,每个线程都有自己...

Global site tag (gtag.js) - Google Analytics