从定义上说ThreadLocal表示的是当前线程的本地变量
理解一下就是表示当前线程的一个变量,这个变量和其他线程完全隔离,只能在当前线程内访问
源码如下
public T get() { Thread t = Thread.currentThread(); // <1> 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; } public void set(T value) { Thread t = Thread.currentThread(); // <2> ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
重点在在<1> <2>处,获取和设置都使用Thread.currentThread来获取当前线程,是当前线程作为一个KEY值去获取 VALUE
测试代码:
package com.my.pro.dao; import com.my.pro.util.ProThreadLocal; public class ProDAO { public void addDaoValue(String value) { String curThreadParam = ProThreadLocal.instance().get(); System.out.println("DAO curThreadParam : " + curThreadParam); System.out.println("DAO curThreadName : " + Thread.currentThread().getName()); } } package com.my.pro.service; import com.my.pro.dao.ProDAO; import com.my.pro.util.ProThreadLocal; public class ProService { public void addSerValueSer(String value) { String curThreadParam = ProThreadLocal.instance().get(); System.out.println("Service curThreadParam : " + curThreadParam); System.out.println("Service curThreadName : " + Thread.currentThread().getName()); new ProDAO().addDaoValue(value); } } package com.my.pro.util; public class ProThreadLocal { public static ThreadLocalcurThreadLocalParams = new ThreadLocal (); private ProThreadLocal() { } private static class ProThreadLocalHolder { private static ProThreadLocal INSTANCE = new ProThreadLocal(); } public static ProThreadLocal instance() { return ProThreadLocalHolder.INSTANCE; } public String get() { return curThreadLocalParams.get(); } public void set(String prarm) { curThreadLocalParams.set(prarm); } }
执行
package com.my.pro; import com.my.pro.service.ProService; import com.my.pro.util.ProThreadLocal; public class Main { public static void main(String args[]) { Thread threadA = new Thread(new Runnable() { @Override public void run() { ProThreadLocal.instance().set("Param-A"); new ProService().addSerValueSer("-1"); } }); threadA.setName("Thread-a"); threadA.start(); Thread threadB = new Thread(new Runnable() { @Override public void run() { ProThreadLocal.instance().set("Param-B"); new ProService().addSerValueSer("-2"); } }); threadB.setName("Thread-b"); threadB.start(); } }
ThreadLocal类获取提供了get() set()方法来获取值
多次运行结果,Thread-a 和Thread-b中运行的代码以及调用链中的代码都只能获取自己线程的值。
ThreadLocal的使用:
在使用自定义的注解对切面方法进行处理的过程中,需要把返回值传给方法被注解的方法,就可以使用ThreadLocal存储返回值在方法中直接获取。
下次再写个实例。