ThreadLocal的工作原理
场景
假设一个用户是一个线程。他们都对数据库进行操作,这个时候就会每个用户就会从数据源中开启一个事务以确保能够顺利的打开或者关闭事务。那么如何保证用户与用户之间的数据库连接不发生冲突呢?就是用ThreadLocal。
原理解释
这里先交代一下,每一个线程都有自己的一个Map集合叫做ThreadLocalMap他是线程的一个静态内部类它就是用来保存连接的集合,ThreadLocal是一个工具类它负责将一个连接放入到每一个线程的Map集合中。具体来说就是每来一个用户,数据源就会创建一个连接Connection然后ThreadLocal工具类会将这个新创建的Connection添加到新来用户的Map集合中,并且以Map<ThreadLocal,Object>的方式存入。又因为这个Map是每一个线程(用户)所特有的,所以每个线程会从自己的Map中拿出属于自己的Connection,这样用户之间的Connection就不会发生混乱。
![](https://img-blog.csdn.net/20180903085856666?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0OTkzNjMx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
底层源码
当我们要将一个conn放入对应的线程中时调用threadLocal.set()代码如下:
public void set(T value) {
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> Thread t = Thread.currentThread();</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> ThreadLocalMap map = getMap(t);</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> if (map != null)</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> map.set(this, value);</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> else</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> createMap(t, value);</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> }</strong></span></strong></p>
</td>
</tr></tbody></table><p style="margin-left:0pt;"> </p>
当我们想要得到每个线程的conn时:
public T get() {
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> Thread t = Thread.currentThread();</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> ThreadLocalMap map = getMap(t);</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> if (map != null) {</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> ThreadLocalMap.Entry e = map.getEntry(this);</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> if (e != null)</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> return (T)e.value;</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> }</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> return setInitialValue();</strong></span></strong></p>
<p style="margin-left:0pt;"><strong><span style="color:#000000;"><strong> }</strong></span></strong></p>
</td>
</tr></tbody></table><p style="margin-left:0pt;"><span style="color:#000000;">不难发现,get和set操作都是对当前线程做操作。</span></p>
这就是著名的ThreadLocal。
原文地址:https://blog.csdn.net/qq_34993631/article/details/82343689
相关阅读:
python 判断矩阵中每行非零个数的方法
用Python 绘制分布(折线)图
统计numpy数组中每个值出现的个数
pandas 获取不符合条件的dataframe
Python 中如何判断 list 中是否包含某个元素
docker与Spring boot的集成:docker-maven-plugin使用
处理kdevtmpfsi挖矿病毒
使用docker-maven-plugin推送镜像到远程docker服务器
docker 开启2375端口,提供外部访问docker
Spring Boot 配置优先级顺序
原文地址:https://www.cnblogs.com/jpfss/p/9913319.html
Copyright © 2011-2022 走看看
|
|