-
ThreadLocal可以用来存储当前线程的一些数据,每一个Thread对象中,都有一个ThreadLocalMap属性,key为ThreadLocal,vaule为Oject数据,ThreadLocal类中有一个静态内部类ThreadLocalMap,由ThreadLocal和value组成一个弱引用的Entry对象
-
set的时候,先获取当前线程对象,将当前ThreadLocal作为key,值为value封装成一个ThreadLocalMap,然后设置进去当前线程Thread中的ThreadLocalMap中
-
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
-
-
get的时候,将当前ThreadLocal对象作为key,从当前Thread对象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(); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
-
-
内存泄漏的情况
- 线程池中的线程一般都是重复利用的,那么该线程中的ThreadLocalMap也一直存在,ThreadLocalMap中的ThreadLocal对象也会一直存在并且不断的增加(用完的不会清楚掉),所以可能会泄露。
- 每次使用完ThreadLocal都要调用remove()方法清除数据
- 使用private static
-
使用场景
-
public class Person { private ThreadLocal<String> name = new ThreadLocal<>(); private ThreadLocal<String> location = new ThreadLocal<>(); public String getName() { return this.name.get(); } public void setName(String name) { this.name.set(name); } public String getLocation() { return this.location.get(); } public void setLocation(String location) { this.location.set(location); } } vpublic class ThreadUseTest { public static void main(String[] args) { Person person = new Person(); new Thread(new Runnable() { @Override public void run() { person.setLocation("guangdong"); person.setName("johnbarrowman"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(person.getLocation()+ person.getName()); } }).start(); new Thread(new Runnable() { @Override public void run() { person.setLocation("guangdong1"); person.setName("johnbarrowman1"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(person.getLocation()+ person.getName()); } }).start(); } }
-
Q.E.D.