浅谈ThreadLocal

一、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的用法,简单使用是没有问题的。但还是有两个问题无法解决:

  1. 高并发的情况下,可能多个线程同时获取到数据库连接,就会产生并发的问题。我们想到可以使用同步锁来处理,保证只有一个线程获取到数据库连接,但这样毫无疑问效率非常低。
  2. 如果有多条sql需要执行,需要用同一个connection对象。那就需要在多个方法中传递这个connection对象,方法传递会有点麻烦。
    那么有没有更好的方法呢,就是本文讲到的ThreadLocal了。我们稍微修改一下:
public class ConnectionManager {
    private static String url ="***";

    private static final ThreadLocal threadLocal = new  ThreadLocal();

    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的两点好处:

  1. 每个线程有自己的ThreadLocalMap对象,线程各自访问各自的,提供了保存对象到线程的方法。
  2. 减少了线程间传递参数的麻烦。

基于这样两点好处,我们在获取数据库连接,获取session,获取token信息等场景下使用ThreadLocal会很方便。

你可能感兴趣的:(浅谈ThreadLocal)