美文网首页技术总结
关于一些ThreadLocal的认识

关于一些ThreadLocal的认识

作者: AlanKim | 来源:发表于2017-11-07 20:21 被阅读37次

    ThreadLocal的主要实现如下:

    ThreadLocal中有一个静态内部类,名为ThreadLocalMap,主要定义如下:

         * 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.
         */
        static class ThreadLocalMap {
    
            /**
             * The entries in this hash map extend WeakReference, using
             * its main ref field as the key (which is always a
             * ThreadLocal object).  Note that null keys (i.e. entry.get()
             * == null) mean that the key is no longer referenced, so the
             * entry can be expunged from table.  Such entries are referred to
             * as "stale entries" in the code that follows.
             */
            static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }
    

    注意看其中的说明:

    • ThreadLocalMap是个定制的HashMap,所以很多HashMap的实现,这里其实都有类似的东西。
    • ThreadLocalMap的Entrty元素,注意是WeakReference类型,想想weakReference的特点嘞,它跟SoftReference的区别就是:
      • SoftReference指向的对象,只有在内存不足时才会被GC回收掉。
      • 只有WeakReference指向的对象,在下次GC的时候一般就会回收掉。
        所以这个Entry继承WeakReference,应该只是为了当一个线程结束时,其对应的ThreadLocal数据会尽快的被释放掉。
    • Entry中的key值是ThreadLocal本身,value则是你需要存储的数据(Object类型),所以对应到HashMap,可以想到其hashcode就是key的hashcode。
    • 每个线程独享一个ThreadLocalMap,比如一个Thread的实现,里面定义了4个ThreadLocal,那么在实际代码运行过程中,只会有一个ThreadLocalMap实例,里面包含了至少4个Entry,分别对应上述的几个ThreadLocal对象。而多个Thread之间,ThreadLocalMap是不共用的,每个线程对象自己维护自己的ThreadLocalMap。
    • 关于ThreadLocalMap存放在哪儿,其实跟正常的java对象一样,都是存放在堆空间里,通过线程来获取,如下:
    class Thread implements Runnable {
        /* Make sure registerNatives is the first thing <clinit> does. */
        private static native void registerNatives();
        static {
            registerNatives();
        }
    
        private volatile String name;
        ...
        /* ThreadLocal values pertaining to this thread. This map is maintained
         * by the ThreadLocal class. */
        ThreadLocal.ThreadLocalMap threadLocals = null;
    
      ...
    

    通过线程对象 t.threadLocals就可以获取到整个ThreadLocalMap,然后再根据key值获取存入的结果。

    • 这里之前看的时候,没有仔细去看对应的实现,以为是放在线程在初始化的时候指定的-Xss分配的堆空间内,但是仔细看过代码之后,发现两者并无关联。这里还是理解不够深,-Xss指定的是Stack space,也就是栈空间,其中是不会存放对象的。

    相关文章

      网友评论

        本文标题:关于一些ThreadLocal的认识

        本文链接:https://www.haomeiwen.com/subject/tkcsmxtx.html