一、介绍
ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,ThreadLocal 的作用
是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或
者组件之间一些公共变量的传递的复杂度。
ThreadLocalMap(线程对象的一个属性)
- 每个线程中都有一个自己的ThreadLocalMap 类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
- 将一个共用的ThreadLocal 静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap 中,然后在线程执行的各处通过这个静态ThreadLocal 实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。
- ThreadLocalMap 其实就是线程里面的一个属性,它在Thread 类中定义
ThreadLocal.ThreadLocalMap threadLocals = null;
二、用途
用途1: 同一个线程中,上下文调用用来进行参数传递,避免下游每个接口都定义同样的参数进行接收
/**
* mysql接口公共参数工具类
* @author leiyijia
*
*/
public class MysqlCommonRequestUtils {
private static ThreadLocal<MysqlCommonRequest> threadCommonRequest = new ThreadLocal<MysqlCommonRequest>();
/**
* 设置mysql接口的公共参数
* @param tableName 操作的表名
* @param serviceId 业务标识
*/
public static void setCommonRequest(String tableName, String serviceId) {
threadCommonRequest.set(new MysqlCommonRequest(tableName, serviceId));
}
/**
* 获取当前线程mysql接口的公共参数
*/
public static MysqlCommonRequest getCommonRequest() {
return threadCommonRequest.get();
}
/**
* 删除当前线程mysql接口的公共参数
*/
public static void remove() {
threadCommonRequest.remove();
}
}
作用2:连接池
由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection
不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个
Connection,这样的话是没有办法完成一个事务的。
DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那
么这些 DAO 就会被纳入到同一个 Connection 之下。
ThreadLocal能够实现当前线程的操作都是用同一个Connection,保证了事务!
public class ThreadLocalPool{
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
public static Connection getConnection() {
Connection conn = threadLocal.get(); //从当前线程取连接
if(null == conn){
conn = DriverManager.getConnection();//从连接池中取一个连接
threadLocal.set(conn);
}
return conn;
}
}