关于ThreadLocal
2020-10-29 本文已影响0人
From64KB
先从一个案例开始入手:
image.png
image.png
所有的线程都使用同一个
image.png
通过上图的代码,就可以保证,每个线程只有一个
image.png
image.png
image.png
至于从事Android开发那就更绕不开这个类了,

有这样一个场景,多个线程查询用户的出生日期,其中birthDate(int userId)
会将用户的出生日期格式化后返回。注意一个问题,就是每次调用birthDate(int userId)
就会生成一个 SimpleDateFormat
对象,这显然是没有必要的。那么这样呢?

所有的线程都使用同一个
SimpleDateFormat
对象,这样又会遇到一个问题, SimpleDateFormat
对象并不是一个线程安全的对象,这样是线程不安全的。如果是使用线程锁限制线程访问,这样又会影响运行速度。那么最理想的情况应该是每个线程只有一个SimpleDateFormat
对象 既解决了生成过多对象占用内存的问题,又能解决多线程线程锁带来的性能问题。这就引入了ThreadLocal
。
通过上图的代码,就可以保证,每个线程只有一个
SimpleDateFormat
对象,解决了生成过多对象占用内存的问题,又能解决多线程线程锁带来的性能问题。
再来讲另外一个ThreadLocal
的案例:

有一个request
需要通过四个Service
才能完成,每个Service
都需要包含用户信息的对象User
,那么就需要把User
对象从Service-1
一直传递到Service-4
,如果不想这样传来传去,怎么办?解决的方案还是ThreadLocal
,可以把User
对象保存在ThreadLocal
中,在需要的地方取出来就行。请求结束后,清空即可ThreadLocal.remove()
。

这样ThreadLocal
的初步使用案例就介绍到这里。如果是从事后台开发,Spring源码中有很多使用ThreadLocal
的地方,例如:

至于从事Android开发那就更绕不开这个类了,
Looper
就是基于ThreadLocal
实现的。