概述
说起threadlocal类,就不得不说一下Java的一个同步机制–synchronized关键字
这个关键字的作用就是控制线程之间的同步问题,当有多个线程访问同一个变量
时,会为这个访问的线程加一把锁,然后就可以高枕无忧的使用这个共享的变量
了。任何其他的线程想要访问这个变量就必须先获得这把锁,只要当前线程不释放
这把锁,其他线程就只能一直等着。所以说synchronized关键字其实就是提供了一
种共享变量的互斥访问机制。而ThreadLocal刚好与之相反,其用来实现线程之间的
变量隔离,当使用threadlocal维护变量时,每个使用该变量的线程中都会有一个该
变量的备份,这样线程之间就不用相互竞争了,线程操作该变量时其实只是在操作
线程中的这个备份而不会对其他线程中的该变量造成任何影响,从而保证了变量的
隔离。
实现原理
上面说到了对于threadlocal的一些理解,下面将会讲到这个机制的实现原理(只会分析部分代码),其相关实现在ThreadLocal类中
先看下get方法的实现
首先获取当前的线程,然后调用getMap获取到一个ThreadLocalMap类型的map,如果map不为空则以当前ThreadLocal对象为key,获取map中对应的value,如果为空则调用setInitialValue方法。
下面具体分析该方法中的各种调用的作用,首先是getMap方法
即返回线程的threadLocals变量,结合上面的分析可知getmap()其实就是获取当前线程的threadLocals变量
可以看出这个变量是ThreadLocal.ThreadLocalMap类型的,即ThreadLocal类的内部类,下面是该类的部分实现
很好理解,就是以ThreadLocal对象为key,value为具体设置的值
上述get方法中还有一种情况是当前线程的ThreadLocalMap为空时,会调用
setInitialValue方法,那么这个方法的作用是什么呢??
对这段代码的理解是:
首先获取当前线程,然后调用getMap得到线程内部的ThreadLocalMap对象,
如果map不为空则调用set方法,如果为空则调用createMap方法,不管是哪种方法,初始时传入的value都为null
来看一下createMap方法的实现:
其实就是创建一个ThreadLocalMap对象,并赋值给线程的threadLocal变量
下面总结一下:
每个线程中都有一个ThreadLocal.ThreadLocalMap类型的变量,用来保存我们希望进行线程隔离的变量副本,初始时为空,当调用get或者set方法时就会以ThreadLocal变量为key,以设置的值为value保存到这个map中,之后想用的话直接get就行了。
使用案例
ThreadLocal变量可以作为一个全局变量,在整个线程中共享,而对其他线程隔离,这样就为我们提供了一种思路:比如连接数据库时,每个线程的连接是隔离的,这样就可以使用ThreadLocal保存这个变量,而且因为是在线程内部共享的,我们就没必要频繁地进行连接的创建和关闭了,从而一定程度上提高了性能。