一句话总结
将T value存到当前线程的Map中,键为ThreadLocal对象,值为T value
ThreadLocal是什么
一个可以保存变量在现场内部的类
ThreadLocal可以做什么
保存变量,使变量仅对对应的线程起作用
ThreadLocal怎样使用
ThreadLocal.set(T value) :写入一个值到ThreadLocal对象中
T ThreadLocal.get() :得到写入的值
ThreadLocal.remove():移除写入的值
ThreadLocal在哪些情况下使用
多线程多实例(每一个线程对应一个实例)的对象访问
使用实例:使用THreadLocal保存Connection对象进行事务控制
/**
* 将Connection保存到当前线程中,单实例
*
* @author Administrator
*
*/
public class ConnectionContext {
private ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
private static ConnectionContext instance = new ConnectionContext();
private ConnectionContext() {
}
public static ConnectionContext getInstance() {
return instance;
}
/**
* 将Connection对象绑定到当前线程中,键为connectionThreadLocal对象,值为connection对象
*
* @param connection
*/
public void bind(Connection connection) {
connectionThreadLocal.set(connection);
}
/**
* 得到绑定的Connection对象
*
* @return
*/
public Connection get() {
return connectionThreadLocal.get();
}
/**
* 移除绑定的Connection对象
*/
public void remove() {
connectionThreadLocal.remove();
}
}
原理分析
public class ThreadLocal<T> {
//设置一个value
public void set(T value) {
//获取调用当前ThreadLocal对象的线程
Thread t = Thread.currentThread();
/*
*得到此线程的ThreadLocalMap,每一个线程中都有一个
*ThreadLocal.ThreadLocalMap threadLocals 对象
*
*ThreadLocalMap getMap(Thread t) {
* return t.threadLocals;
*}
*/
ThreadLocalMap map = getMap(t);
//将变量value保存入此map的值中,键为调用此方法的ThreadLocal对象
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//获取保存的value值
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;
}
}
/*
*如果没放入值则返回初始化值
*默认初始化值为null,可以通过继承重写的方式设定初始化值
*protected T initialValue() {
* return null;
*}
*/
return setInitialValue();
}
static class ThreadLocalMap {
}
//清除value
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
...
...
}