⼀、什么是ThreadLocal

声明:本⽂使⽤的是JDK 1.8

⾸先我们来看⼀下JDK的⽂档介绍:

结合我的总结可以这样理解:ThreadLocal提供了线程的局部变量,每个线程都可以通过 set() 和get() 来对这个局部变量进⾏操作,但不会和其他线程的局部变量进⾏冲突,实现了线程的数据隔离简要⾔之:往ThreadLocal中填充的变量属于当前线程,该变量对其他线程⽽⾔是隔离的。

⼆、为什么要学习ThreadLocal?

从上⾯可以得出:ThreadLocal可以让我们拥有当前线程的变量,那这个作⽤有什么⽤呢???

2.1管理Connection

最典型的是管理数据库的Connection:当时在学JDBC的时候,为了⽅便操作写了⼀个简单数据库连接

池,需要数据库连接池的理由也很简单,频繁创建和关闭Connection是⼀件⾮常耗费资源的操作,因此需要创建数据库连接池~

那么,数据库连接池的连接怎么管理呢??我们交由ThreadLocal来进⾏管理。为什么交给它来管理呢??ThreadLocal能够实现当前线程的操作都是⽤同⼀个Connection,保证了事务!

当时候写的代码:

同样的,Hibernate对Connection的管理也是采⽤了相同的⼿法(使⽤ThreadLocal,当然了Hibernate的实现是更强⼤的)

2.2避免⼀些参数传递

避免⼀些参数的传递的理解可以参考⼀下Cookie和Session:

每当我访问⼀个⻚⾯的时候,浏览器都会帮我们从硬盘中找到对应的Cookie发送过去。浏览器是⼗分聪明的,不会发送别的⽹站的Cookie过去,只带当前⽹站发布过来的Cookie过去浏览器就相当于我们的ThreadLocal,它仅仅会发送我们当前浏览器存在的Cookie(ThreadLocal的局部变量),不同的浏览器对Cookie是隔离的(Chrome,Opera,IE的Cookie是隔离的【在Chrome登陆了,在IE你也得重新登陆】),同样地:线程之间ThreadLocal变量也是隔离的....

那上⾯避免了参数的传递了吗??其实是避免了。Cookie并不是我们⼿动传递过去的,并不需要写

<input name= cookie/> 来进⾏传递参数...

在编写程序中也是⼀样的:⽇常中我们要去办理业务可能会有很多地⽅⽤到身份证,各类证件,每次我

们都要掏出来很麻烦

⽽如果⽤了ThreadLocal的话,ThreadLocal就相当于⼀个机构,ThreadLocal机构做了记录你有那么多张证件。⽤到的时候就不⽤⾃⼰掏了,问机构拿就可以了。

在咨询时的时候就告诉机构:来,把我的身份证、房产证、学⽣证通通给他。在办理时⼜告诉机构:来,把我的身份证、房产证、学⽣证通通给他。...

 

这样是不是⽐⾃⼰掏⽅便多了。

当然了,ThreadLocal可能还会有其他更好的作⽤,如果知道的同学可在评论留⾔哦~~~

三、ThreadLocal实现的原理

想要更好地去理解ThreadLocal,那就得翻翻它是怎么实现的了~

⾸先,我们来看⼀下ThreadLocal的set()⽅法,因为我们⼀般使⽤都是new完对象,就往⾥边set对象了

上⾯有个ThreadLocalMap,我们去看看这是什么?

 

通过上⾯我们可以发现的是ThreadLocalMapThreadLocal的⼀个内部类。⽤Entry类来进⾏存储

我们的值都是存储到这个Map上的,key是当前ThreadLocal对象!

如果该Map不存在,则初始化⼀个:

如果该Map存在,则从Thread中获取!

Thread维护了ThreadLocalMap变量

从上⾯⼜可以看出,ThreadLocalMap是在ThreadLocal中使⽤内部类来编写的,但对象的引⽤是在

Thread中!

于是我们可以总结出:Thread为每个线程维护了ThreadLocalMap这么⼀个Map,⽽ThreadLocalMapkeyLocalThread对象本身,value则是要存储的对象有了上⾯的基础,我们看get()⽅法就⼀点都不难理解了:

 

3.1ThreadLocal原理总结

1. 每个Thread维护着⼀个ThreadLocalMap的引⽤

2. ThreadLocalMap是ThreadLocal的内部类,⽤Entry来进⾏存储

3. 调⽤ThreadLocal的set()⽅法时,实际上就是往ThreadLocalMap设置值,key是ThreadLocal对

象,只是传递进来的对象

4. 调⽤ThreadLocal的get()⽅法时,实际上就是往ThreadLocalMap获取值,key是ThreadLocal对象

5. ThreadLocal本身并不存储值,它只是作为⼀个key来让线程从ThreadLocalMap获取value

正因为这个原理,所以ThreadLocal能够实现“数据隔离”,获取当前线程的局部变量值,不受其他线程

影响