ThreadLocal

简介
ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的ThreadLocal变量。

初始化

//简单初始化
public static final ThreadLocal<T> holder = new ThreadLocal<T>();
holder.set("test"); // 存
holder.get(); // 取
//带初始值初始化
private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>() {
        @Override
    protected String initialValue() {
        return "This is the initial value";
    }
};

例子1

public class ThreadLocalExample {

    public static class MyRunnable implements Runnable {

        private ThreadLocal threadLocal = new ThreadLocal();

        @Override
        public void run() {
            threadLocal.set((int) (Math.random() * 100D));
            try {
            Thread.sleep(2000);
            } catch (InterruptedException e) {

            }
            System.out.println(threadLocal.get());
        }
    }

    public static void main(String[] args) {
         MyRunnable sharedRunnableInstance = new MyRunnable();
         Thread thread1 = new Thread(sharedRunnableInstance);
         Thread thread2 = new Thread(sharedRunnableInstance);
         thread1.start();
         thread2.start();
    }

}

源码分析
1、Thread类中持有ThreadLocal.ThreadLocalMap threadLocals

ThreadLocal.ThreadLocalMap threadLocals = null;

2、ThreadLocal的存取是对Thread类中的ThreadLocalMap进行操作;
ThreadLocalMap中的set方法中的key为ThreadLocal对象

public void set(T value) {
      //获取当前线程
      Thread t = Thread.currentThread();
      //当前线程的ThreadLocalMap
      ThreadLocalMap map = getMap(t);
      if (map != null)
          //key为this,表示当前ThreadLocal对象
          map.set(this, value);
      else
          createMap(t, value);
  }

3、ThreadLocalMap中的set方法,如果发生了Hash碰撞,在循环条件中可以看到nextIndex,即找到下个位置存放。该Hash碰撞冲突解决方式属于线性探测再散列。

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;
        }
    }

4、ThreadLocalMap中的Entry数组为弱引用

static class Entry extends WeakReference<ThreadLocal> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal k, Object v) {
        super(k);
        value = v;
    }
}

5、内存溢出问题
http://blog.xiaohansong.com/2016/08/06/ThreadLocal-memory-leak/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值