见到此篇文章的小伙伴移动到这篇新的文章~ updateby xiaojuzi 20231117
https://blog.youkuaiyun.com/weixin_45554996/article/details/134471184
1.ThreadLocal是什么?到底有什么用?
ThreadLocal我们可以叫做线程本地变量,它为每个使用该变量的线程提供了独立的变量副本,所以每一个线程都可以独立改变自己的副本,而不会影响其他线程所对应的副本。每个线程可以有多个副本哦,通过ThreadLocalMap进行存储,key是ThreadLocal,value是你设置的值。
2.它的经典使用场景
1.数据库连接
/**
负责数据库连接定义的程序类
该类可以负责所有操作线程的数据库连接,利用get()方法可以获得连接对象
/
public class DatabaseConnection {
private static final String DBDRIVER = “oracle.jdbc.driver.OracleDriver” ;
private static final String DBURL = “jdbc:oracle:thin:@localhost:1521:orcl” ;
private static final String USER = “scott” ;
private static final String PASSWORD = “tiger” ;
private static ThreadLocal threadLocal = new ThreadLocal() ;
/
* 负责对外部提供获取的数据库连接对象,该对象通过ThreadLocal获取,如果当前线程没有保存的连接对象,则创建新的连接
* @return 连接对象
/
public static Connection getConnection() {
Connection conn = threadLocal.get() ; // 先判断一下在ThreadLocal里是否有连接对象
if(conn == null) { // 第一次使用,没有连接,没有连接应该创建一个连接
conn = connectionDatabase() ; // 获取连接对象
threadLocal.set(conn); // 将刚刚创建好的连接对象保存在ThreadLocal之中
}
return conn ; // 返回连接对象
}
/
* 进行数据库的关闭处理。
/
public static void close() {
Connection conn = threadLocal.get() ;
if (conn != null) { // 现在有连接对象了
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
threadLocal.remove(); // 从当前线程之中删除掉指定连接
}
}
/*
* 负责创建一个数据库连接对象
* @return 数据库连接的实例化对象
*/
private static Connection connectionDatabase() { // 该方法只能本类调用
Connection conn = null ;
try { // 一旦连接出现了错误,整个程序都无发执行
Class.forName(DBDRIVER) ;
conn = DriverManager.getConnection(DBURL, USER, PASSWORD) ;
} catch (Exception e) {
e.printStackTrace();
}
return conn ; // 获得数据库连接对象
}
}
2.session管理
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure() .buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session =
new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
3.它带来的问题
ThreadLocal会导致内存泄漏哦,为什么呢?因为只有线程结束的时候它所对应的ThreadLocal对象才会回收哦,想想并发~
4.最佳实践
每次使用完ThreadLocal,都调用它的remove()方法,清除数据哦。