码迷,mamicode.com
首页 > 编程语言 > 详细

Java ThreadLocal 运行机制

时间:2020-05-02 14:43:08      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:map   添加   private   机制   oca   get   hash   nec   table   

ThreadLocal可以很方便的在一个线程运行周期内传递各种数据,而不用在调用栈的每个方法上添加新的参数

它的运行机制也比较简单,每个线程实例内部都会有一个 ThreadLocal.ThreadLocalMap  threadLocals(类型具体定义在ThreadLocal.class 内部)类型的字段,在调用ThreadLocal.set的时候会将自己实例作为key和value包装到一个Entry类型实例里一起存储在threadLocals的table中,因为是数组类型,所以会根据ThreadLocal实例的hashcode和数组长度做 & 运算,计算出位置,这里解决hash冲突的方式用的是开放定址法(好像是?),在发现一个位置已经存放了数据后,会向后移动一个位置,直到那里没有被使用或者ThreadLocal的实例被回收。

private void set(ThreadLocal<?> key, Object value) {
            ...
            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);
            for (Entry e = tab[i];
                 e != null;
                 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal<?> k = e.get();
                if (k == key) {
                    e.value = value;
                    return;
                }

                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            ...
        }

  

为什么ThreadLocal在table中有引用还是会被回收呢?由于在Entry类型中k是WeakReference,当ThreadLocal实例不被强引用后就会被回收,但对应Entry实例并不会被回收,依然还在table里(似乎会产生泄漏,一部分内存没有被使用也无法被回收),下面看一下threadLocals的类型定义

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;
            }
        }
     /**
     * The table, resized as necessary.
     * table.length MUST always be a power of two.
     */
     private Entry[] table;
}

 

Java ThreadLocal 运行机制

标签:map   添加   private   机制   oca   get   hash   nec   table   

原文地址:https://www.cnblogs.com/zhujiayi/p/12817988.html

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