一、概述
ThreadLocal,即线程局部变量。主要用于线程间数据隔离。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是private static类型。ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。ThreadLocal的主要应用场景为按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。例如:同一个网站登录用户,每个用户服务器会为其开一个线程,每个线程中创建一个ThreadLocal,里面存用户基本信息等,在很多页面跳转时,会显示用户信息或者得到用户的一些信息等频繁操作,这样多线程之间并没有联系而且当前线程也可以及时获取想要的数据。
二、原理
ThreadLocal如何实现线程独立访问ThreadLocal关联的变量呢?
这里主要有两种方式:
在ThreadLocal中维护一个map,map的key是线程,value是关联的变量。但这种方式不太优雅(JDK1.5之前采用的这种方式),比如说可能会导致线程很大,而且当线程销毁时,还需要在map中将其删除,在多线程情形下,会增加维护难度和时间成本。
每个Thread维护一个ThreadLoaclMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object。这样做有很多好处,比如不用加锁来保证读写安全,而且当线程销毁时,与其关联的ThreadLocalMap也自然消亡。