ThreadLocal
1. ThreadLocal是如何为每个线程创建变量的副本的:
1). 首先,在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,
value为变量副本(即T类型的变量)。
2). 初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,
以ThreadLocal要保存的副本变量为value,存到threadLocals。
3). 然后在当前线程里面,如果要使用副本变量,就可以通过get方法在threadLocals里面查找。
2. set方法中会获取当前线程的threadLocals,然后当前ThreadLocal(假设为:threadLocal)作为key,value值作为threadLocals的value值。因为threadLocals是每个线程私有的,所以不同线程取值时,
虽然都调用threadLocal.get(),当get方法回去不同的线程中取不同的threadLocals,然后取到各个线程中的value值。
3. 最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。
数据库:
private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { public Connection initialValue() { return DriverManager.getConnection(DB_URL); } }; public static Connection getConnection() { return connectionHolder.get(); }
Session管理:
private static final ThreadLocal threadSession = new ThreadLocal(); public static Session getSession() throws InfrastructureException { Session s = (Session) threadSession.get(); try { if (s == null) { s = getSessionFactory().openSession(); threadSession.set(s); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } return s; }
4. ThreadLocal变量为静态的,保证每个线程在任何地方都可以使用相同的key值。
时间: 2024-11-09 03:43:33