码迷,mamicode.com
首页 > 其他好文 > 详细

ThreadLocal

时间:2018-05-29 19:02:30      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:shm   移除   for   reference   entry   else   引用队列   容量   adl   

一、概述
下面是jdk文档对ThreadLocal的描述。

ThreadLocalMap is a customized hash map suitable only for maintaining thread local values. No operations are exported outside of the ThreadLocal class. The class is package private to allow declaration of fields in class Thread. To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys. However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space.

翻译:
ThreadLocalMap仅仅是为了维持线程本地变量值而自定义的hash结构。不会有操作被暴露到ThreadLocal外。
为了应对大对象或存活时间较长的对象,hash表的Entry使用的WeakReferences作为key。
然而,当引用队列不再被使用时,Entry就不再被使用了,必须保证它被移除,仅当hash表用完了空间。


二、使用

ThreadLocal一般都是声明在static变量中的,如果不断的创建ThreadLocal而没有调用其remove方法,将会导致内存泄漏,特别是在高并发的web容器中这么做的时候。


三、应用场景
1.Spring中用来管理数据库资源
2.Struts2中通过ActionContext来获取相应的对象,每个线程获取的都是自己的数据。
3.数据传递
在同一请求中,可以传递数据。一次请求先经过拦截器后再进入controller,在拦截器中需要查询用户信息,而进入了controller之后可能又需要使用该用户信息,这时可以使用ThreadLocal来保存数据,因此一次请求对应的是同一个线程。

四、源码分析

    public T get() {
        // 获取当前线程
        Thread t = Thread.currentThread();
        // 获取当前线程绑定的ThreadLocalMap
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        // 获取不到值,则自动为其设置一个初始值并返回。
        return setInitialValue();
    }
    
    public void set(T value) {
        // 获取当前线程
        Thread t = Thread.currentThread();
        // 获取当前线程绑定的ThreadLocalMap
        ThreadLocalMap map = getMap(t);
        if (map != null)
            // 
            map.set(this, value);
        else
            createMap(t, value);
    }
    
    // 获取线程绑定的ThreadLocalMap
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

ThreadLocal并未使用HashMap来作为存储结构,而是重新实现了一个类似于HashMap的Map数据结构
先来看看ThreadLocalMap的实现。

 

初始容量为16,负载因子为2/3。

    static class ThreadLocalMap {
        
        static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
            Object value;
            
            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }    
    }

 

五、避免内存泄漏

 

ThreadLocal

标签:shm   移除   for   reference   entry   else   引用队列   容量   adl   

原文地址:https://www.cnblogs.com/rouqinglangzi/p/9106301.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!