在每个线程里面维护着这样一个集合。(Thread 里面),这个就可以放一些私有变量。
ThreadLocal.ThreadLocalMap
threadLocals =
null;
重get 方法可以看出,首先会去当前线程拿到map。
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); //t.threadLocals if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
首先会去当前线程拿map,如果没有就创建,创建后也会保持之thread 中。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
这里的key 是this,就是对象的实例,所以在一个线程里是可以new多个threadLocal的。
一般
threadLocal放一些
Session,或者数据库连接时,放一些连:
最后放一个网上的案例,自己就不写了。
优点:
各自线程维护自己的变量,能在线程里任何位置设置值,读取值,不需要通过参数在方法或对象中显示传递。
/** * 数据库连接管理类 * @author 爽 * */ public class ConnectionManager { /** 线程内共享Connection,ThreadLocal通常是全局的,支持泛型 */ private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); public static Connection getCurrConnection() { // 获取当前线程内共享的Connection Connection conn = threadLocal.get(); try { // 判断连接是否可用 if(conn == null || conn.isClosed()) { // 创建新的Connection赋值给conn(略) // 保存Connection threadLocal.set(conn); } } catch (SQLException e) { // 异常处理 } return conn; } /** * 关闭当前数据库连接 */ public static void close() { // 获取当前线程内共享的Connection Connection conn = threadLocal.get(); try { // 判断是否已经关闭 if(conn != null && !conn.isClosed()) { // 关闭资源 conn.close(); // 移除Connection threadLocal.remove(); conn = null; } } catch (SQLException e) { // 异常处理 } } }