简介
官方文档有道之后的结果。
该类提供线程本地变量。这些变量与一般的变量不同,每个线程访问一个线程(通过get或set方法)有自己独立的变量初始化副本。ThreadLocal实例通常是私有的静态字段在类希望关联状态的线程(例如,一个用户ID或交易ID)
个人理解:通过set() 方法将变量实例申明到一个和线程绑定的单独空间,或者理解为使用key-value形式存储变量,线程为key,set的变量实例为value,使用get() 方法获取时即用当前线程去取对应的value。这样就会在各个线程之间互不干扰的使用同一个变量名的不同变量实例,存取也不用担心线程问题。
情景假设
客户端向服务器请求数据库数据,每次请求都需要对数据库进行操作,每一次的请求都通过new Thread的形式创建线程异步处理,这样的话每一次请求都需要建立一个数据库Connection,当然可以在每个线程创建Connection但是不方便进行封装。
// 创建线程局部变量 方便使用全局调用
public static final ThreadLocal<Map<String, Connection>> LOCAL = new ThreadLocal<>();
/**
* 根据表名建立数据库连接
*
* @author fengzhen
* @version v1.0, 2017/9/4 10:40
*/
public static Connection getConDb(String dbName) throws SQLException, ClassNotFoundException {
Map<String, Connection> connectionMap = LOCAL.get();
if (connectionMap == null){
connectionMap = new HashMap<>();
LOCAL.set(connectionMap);
}
Connection conn = connectionMap.get(dbName);
if (conn == null || conn.isClosed()) {
conn = DriverManager.getConnection(DBUtils.SQLSERVER_URL + dbName, DBUtils.USER, DBUtils.PASSWORD);
connectionMap.put(dbName,conn);
}
return conn;
}
如上,之后想要获取Connection可以直接通过 LOCAL.get() 获取当前线程建立的Connection,而不用考虑线程的问题。
常用方法
set()
将当前线程的本地变量的副本设置为指定的值。
即相当于map的put方法,存入数据。
get()
返回当前线程的本地线程变量的值。
即,get方法,使用线程为key取值。
remove()
为该线程本地变量移除当前线程的值。
即,remove方法
initialValue()
返回该线程本地变量的当前线程的“初始值”。该方法将第一次调用一个线程访问变量的get()方法,除非线程之前调用的set(T)的方法,在这种情况下,初值的方法不会被调用的线程。通常情况下,这种方法是每个线程调用一次,但它可能在后续调用remove()随后get()再次调用。
这简单执行返回null;如果程序员渴望线程局部变量有一个初始值非零,ThreadLocal必须子类,并重写这个方法。通常,匿名内部类将被使用。