ThreadLocal 变量的基本使用和拓展解读

        Java开发中,多线程是必不可少的要接触的技术。在多线程的环境中,有的时候需要多个线程操作同一个变量,有的时候需要针对每一个线程都使用自己的变量值互不影响。针对每一个线程使用自己私有的本地变量的情况,java为我们提供了一个类库---TheadLocal,帮助我们解决这个问题。

 

 项目中实际遇到的问题:

         因为数据库日益访问的压力增大,所以需要将主要的数据仓库redshift的数据按照一定的业务逻辑,copy计算后的三个月数据到mariaDB进行存储并做定时的更新处理。可以理解为类似于redis等缓存型数据库进行数据缓存供前台查询操作。随之而来的问题是怎么不改变原本获取数据库连接的代码而为不同的请求(3个月为界限,访问不同的数据库)设置相对应的DataSource。

 

实际的解决方案:

    Web项目的每一个请求,系统都会为之分配线程,所以可以对所有的请求进行过滤或者监听,项目中实际使用监听实现,然后配合ThreadLocal变量为每一个请求set不同的DataSource到本地变量中供后面查询数据库进行get操作。

 

ThreadLocal 使用和分析:

ThreadLocal 变量的基本使用和拓展解读_第1张图片

 

ThreadLocal主要的方法是:get,set,remove以及初始化。

--> 创建一个线程和主线程,分别对ThreadLocal变量进行赋值和取值,观察是否线程私有

ThreadLocal 变量的基本使用和拓展解读_第2张图片

ThreadLocal 变量的基本使用和拓展解读_第3张图片

从输出的打印结果看,每一个线程的本地变量是线程私有的,相互之间只可以获取自己对应线程的数据。

 

-->  ThreadLocal 源码解读(set方法看数据的存储)

ThreadLocal 变量的基本使用和拓展解读_第4张图片

根据ThreadLocal的set方法可以看出,ThreadLocal类本身不对线程中要引用的变量进行存储,而是通过TheadLocalMap进行本地变量的保存,TreadLocal作为key,实际的值作为value。

ThreadLocal 变量的基本使用和拓展解读_第5张图片

而ThreadLocalMap是对HashMap的封装,主要使用的内部类Entry继承自WeakReference。

ThreadLocal 变量的基本使用和拓展解读_第6张图片ThreadLocal 变量的基本使用和拓展解读_第7张图片

 

--> 疑问:remove方法的作用是什么?

        ThreadLocal容易导致内存溢出,因为每一个threadLocal是作为数据保存的key及进行存储的,当程序执行后如果ThreadLocal变量已经没有外部的强引用在引用的话,会被GC回收哦,回收过后ThreadLocalMap中就会存在null key的value,而如果该线程一直不结束,或者多个线程出现这样的情况,null key会一直存在不会被回收,会有内存泄漏的风险。这个时候需要使用remove方法将key移除,所以一般线程使用完本地变量后需要将其移除

ThreadLocal 变量的基本使用和拓展解读_第8张图片

 

--> 补充:

        ThreadLocal变量是线程私有的,所以无法进行子线程的变量传递,为了解决这个问题,我们可以使用他的子类进行子线程和父线程间本地变量共享的情况,请见下回分解。。。

你可能感兴趣的:(Java开发)