ThreadLocal 是一个线程局部变量,同一个 ThreadLocal 所包含的对象在不同的 Thread 中都会对应不同的副本,所以,对于线程 Thread 来说,都有自己的 ThreadLocal,对于其他线程不可见。
做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,可以防止自己的变量被其他线程更改。
Spring采用ThreadLocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式,可以使业务层使用事务时不需要感知并管理connection对象,通过传播级别,能够管理多个事务配置之间的切换,挂起与恢复。 Spring框架里面使用的就是ThreadLocal来实现这种隔离级别,主要是在TransactionSynchronizationManager这个类中。如下为代码
private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal("Transactional resources"); private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal("Transaction synchronizations"); private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal("Current transaction name"); private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal("Current transaction read-only status"); private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal("Current transaction isolation level"); private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal("Actual transaction active");在这里,Spring事务主要是ThreadLocal和AOP去实现的,每个线程自己的链接是靠ThreadLocal保存。
线程进来之后,会初始化一个可以泛型的 ThreadLocal 对象,只要这个线程在 remove 之前去获取相应的值,都是可以获取到的。实现了线程间的数据隔离,不过如果要过去到其他线程中的数据还是有办法的。 我们来看看存储值的方法 set() 的源码:
public void set(T value) { Thread t = Thread.curr