一、ThreadLocal是什么
ThreadLocal是线程本地存储变量,线程将一些变量存储在ThreadLocal对象中。
二、ThreadLocal的用法
ThreadLocal因为只是放线程自身的需要使用的变量,这些变量只有线程自身能够访问,所以并不能解决多线程并发的问题。那么ThreadLocal在什么场景下使用呢?
先看一个常用的例子:
public class ConnectionManager {
private static String url ="***";
private static Connection connect = null;
public static Connection openConnection() throws SQLException {
if(connect == null){
connect = DriverManager.getConnection(url);
}
return connect;
}
public static void closeConnection() throws SQLException {
if(connect!=null)
connect.close();
}
}
获取数据库连接,这是我们刚开始学习jdbc的用法,简单使用是没有问题的。但还是有两个问题无法解决:
- 高并发的情况下,可能多个线程同时获取到数据库连接,就会产生并发的问题。我们想到可以使用同步锁来处理,保证只有一个线程获取到数据库连接,但这样毫无疑问效率非常低。
- 如果有多条sql需要执行,需要用同一个connection对象。那就需要在多个方法中传递这个connection对象,方法传递会有点麻烦。
那么有没有更好的方法呢,就是本文讲到的ThreadLocal了。我们稍微修改一下:
public class ConnectionManager {
private static String url ="***";
private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
public static Connection openConnection() throws SQLException {
Connection connect = threadLocal.get();
if(connect == null){
connect = DriverManager.getConnection(url);
threadLocal.set(connect);
}
return connect;
}
}
使用了ThreadLocal后,由于线程访问的都是自己的Connection对象,所以就不存在高并发的问题。同时还解决了事务的问题,同一个事务里,Connection对象不需要传来传去,直接用ThreadLocal获取就可以了。
所以我们总结一下ThreadLocal的两点好处:
- 每个线程有自己的ThreadLocalMap对象,线程各自访问各自的,提供了保存对象到线程的方法。
- 减少了线程间传递参数的麻烦。
基于这样两点好处,我们在获取数据库连接,获取session,获取token信息等场景下使用ThreadLocal会很方便。
网友评论