ThreadLocal不能保证其创建的对象是全局唯一,但能保证在单个线程中是唯一的。
示例:
package com.example.springbootdemo.singleton; public class ThreadLocalSingleton { private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance = new ThreadLocal<ThreadLocalSingleton>(){ @Override protected ThreadLocalSingleton initialValue() { return new ThreadLocalSingleton(); } }; private ThreadLocalSingleton(){} public static ThreadLocalSingleton getInstance(){ return threadLocalInstance.get(); } public static void main(String[] args) { System.out.println(ThreadLocalSingleton.getInstance()); System.out.println(ThreadLocalSingleton.getInstance()); System.out.println(ThreadLocalSingleton.getInstance()); System.out.println(ThreadLocalSingleton.getInstance()); System.out.println(ThreadLocalSingleton.getInstance()); } }
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?
每个线程中都有一个独立的ThreadLocalMap,它所存储的值,只能被当前线程读取和修改
源代码:
public void set(T value) { Thread t = Thread.currentThread(); //拿到当前线程 ThreadLocalMap map = getMap(t); //拿到当前线程里的ThreadLocalMap if (map != null) map.set(this, value); //键值为当前ThreadLocal对象,值为要维护的变量 else createMap(t, value); }
getMap(t)是怎么来的呢? 源码 :
ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
t.threadLocals是啥?
参见Thread类: 原来Thread类有个threadLocals成员变量
/* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap是啥? 原来ThreadLocal有个静态内部类
static class ThreadLocalMap
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
ThreadLocal和传统的synchronized有啥区别?
synchronized是锁机制进行时间换空间,ThreadLocal是存储拷贝进行空间换时间。