当前位置:网站首页>ThreadLocal 总结(未完待续)
ThreadLocal 总结(未完待续)
2022-07-25 22:12:00 【斯沃福德】
ThreadLocal
1. Java内存模型:
- Java所有变量都存储在主内存中
- 每个线程都有自己独立的工作内存,里面保存该线程的使用到的变量副本(该副本就是主内存中该变量的一份拷贝)
- 线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接在主内存中读写,线程修改完变量之后要刷新到主内存中;
- 不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。
线程1对共享变量的修改,要想被线程2及时看到,必须经过如下2个过程:
①把工作内存1中更新过的共享变量刷新到主内存中
②将主内存中最新的共享变量的值更新到工作内存2中
2. 背景
多个线程对一个变量进行写入的时候容易产生线程安全问题,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性;
ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线程访问出现线程不安全的方法;
当我们在创建一个变量后,如果每个线程对其进行访问的时候访问的都是线程自己的变量,这样就不会有线程安全问题了。(以数据隔离的方式来保证线程安全)
3. 概述
ThreadLocal为每一个线程都提供一个专属的变量副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突;
如果你创建了⼀个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的本地副本;
可以使⽤ get() 和 set() ⽅法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题;
例:
ThreadLocal的数据是隔离的,每个线程都能拿到变量的副本,线程2 拿到的还是null !
4. 结构
JDK8之前: key是Thread,由Threadlocal来维护ThreadlocalMap 
JDK8改变结构的好处:
1.Thread作为Key,则线程很多时Entry会很多,而ThreadLocal作为Key,Entry数量会减少很多;key少了就能尽量避免哈希冲突
2.当Thread销毁时,ThreadLocalMap也会随之销毁,减少内存开销;而早期ThreadLocalMap由ThreadLocal维护,线程结束并不会销毁ThreadLocalMap;
JDK8中结构: key是threadLocal对象,由Thread线程来维护threadLocalMap

结构说明:
每个Thread维护一个ThreadLocalMap,
Key是Threadlocal对象,value就是Threadlocal的set方法存的值(变量副本);
对于不同的线程,有着各自不同的ThreadLocalMap,所以就能使数据副本的隔离;
5. set() 、get()、remove()方法源码
5.1 set()
1.先获取当前线程对象;
2.获取线程对象的threadLocals属性,也就是threadLocalMap;
3.如果map存在就将当前threadLocal对象作为key,传入的值作为value传入map; 如果map为空就会创建一个map



5.2 get()
1.获取当前Thread线程对象;
2.获取线程的threadLocals即threadLocalMap;
3.当map存在,以当前的threadLocal对象为key,调用map.getEntry方法拿到Entry实体,若Entry实体不为空则取出Entry试题中的value;
4.①如果map不存在 或 ②没有与当前threadLocal对象关联的Entry调用setInitiavalue()设置初始化方法:
判断map,如果为空则创造map;
如果map不为空则把当前ThreadLocal对象作为key,和value存入map


5.3 remove()
1.获取当前线程对象;
2.获取线程的threadLocals即threadLocalMap;
3.如果map不为空就溢出当前threadLocal对象关联的Entry
6. 内存泄露问题
ThreadLocalMap 中使⽤的 key 为 ThreadLocal 的弱引用,⽽ value 是强引用。所以,如果
ThreadLocal 没有被外部强引⽤的情况下,在垃圾回收的时候,key 会被清理掉,⽽ value 不会被清理掉;
这样⼀来, ThreadLocalMap 中就会出现key为null的Entry,假如我们不做任何措施的话,value 永远⽆法被GC 回收,这个时候就可能会产⽣内存泄露。
ThreadLocalMap实现中已经考虑了这种情况,在调⽤ set() 、 get() 、 remove() 方法的时候,会清理掉 key 为 null 的记录。
使用完ThreadLocal 方法后 最好手动调用 remove() 方法;
边栏推荐
- H5 lucky scratch lottery free official account + direct operation
- C语言:随机生成数+选择排序
- All you want to know about interface testing is here
- El expression improves JSP
- The second short contact of gamecloud 1608
- ZigBee development board (nxpzigbee Development)
- 2022 the latest software tests eight part essay. Whether you can offer depends on how you recite it
- 在腾讯干软件测试3年,7月无情被辞,想给划水的兄弟提个醒...
- 『Skywalking』. Net core fast access distributed link tracking platform
- YUV420 yuv420sp image format "recommended collection"
猜你喜欢

Jmeter---设置代理录制请求

Nuclear power plants strive to maintain safety in the heat wave sweeping Europe

Virtual memory and disk

五种分配方式是否会产生内部碎片、外部碎片

虚拟内存与磁盘

Wet- a good choice for people with English difficulties - console translation

2 lines of code to generate a solid desktop background

Jenkins+svn configuration

Victoriametrics single node of kubernetes

Sofa weekly | open source person - Niu Xuewei, QA this week, contributor this week
随机推荐
The dragon lizard exhibition area plays a new trick this time. Let's see whose DNA moved?
What is class loading? Class loading process?
ansible+Crontab批部署巡检
C language: random generated number + bubble sort
Why is the integer type 128 to byte -128
JSP nine built-in objects
磁盘空间的三种分配方式
Dovecot set mailbox quota
Tfrecord write and read
Title: give a group of arrays, arranged from large to small and from small to large.
3. Editors (vim)
[fan Tan] after the arrival of Web3.0, where should testers go? (ten predictions and suggestions)
『Skywalking』.NET Core快速接入分布式链路追踪平台
jenkins+SVN配置
还不懂mock测试?一篇文章带你熟悉mock
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No suc
关于接口测试你想知道的都在这儿了
4day
『SignalR』. Net using signalr for real-time communication
这次龙蜥展区玩的新花样,看看是谁的 DNA 动了?