揭秘ThreadLocal(.net)

网上有很多关于ThreadLocal的文章,但是很多都是介绍java中的ThreadLocal。今天我来介绍.net中的ThreadLocal的实现原理。

ThreadLocal定义

1:提供数据线程的本地存储,也就是每个线程都有一个变量副本,而且互不影响。
2:为了有一个直观的感受,看一段代码:
在这里插入图片描述
3:此段代码的执行结果如下:其中,3、1代表线程号,后面的王五、李四代表这两个线程对应的各自的值。通过结果可以发现,虽然线程3将值改成了王五,但是当线程1执行的时候,仍然能够输出自己所设置的值,也就是李四。为什么会实现这个效果,继续看。
在这里插入图片描述

原理

1:通过查看ThreadLocal源码发现,实现每个线程都有一个变量副本的关键代码如下:
在这里插入图片描述
是**[ThreadStatic]**使每个线程都有一个变量副本。

2:那么问题来了,[ThreadStatic]是怎么做到的,使每个线程拥有一个变量副本呢?
答案:[ThreadStatic]改变了Clr的默认行为。默认情况下,静态变量是线程共享的,但是当Clr看到静态变量上添加了[ThreadStatic]特性时,就会对该变量做特殊的处理,使得每一个线程单独创一个变量副本。

3:那么问题又来了,为什么是改变了Clr的默认行为,而不是通过编译器生成的IL(中间码)实现的?
3.1:[ThreadStatic]源代码如下:通过这段代码,我们可以发现[ThreadStatic]只是一个定义,没有任何实现。
在这里插入图片描述
3.2:看一下我的代码实现,如下:
在这里插入图片描述
通过ilDasm工具查看,生成的中间码也没有做关于线程本地存储的代码。因此通过排除法,可以证明是通过改变Clr的默认行为来实现线程本地存储的。
在这里插入图片描述

使用场景

1:存储用户session。
2:数据库连接。
3:线程内上下文管理等等。

心得

1:并不是所有的功能都是通过代码实现的。
2:Clr的行为是可以改变的。
3:对于多线程资源共享的问题:不仅仅可以通过加锁的方式来解决,也可以通过让线程本地存储来解决。

参考文章

1:https://stackoverflow.com/questions/5227676/how-does-the-threadstatic-attribute-work
2:https://referencesource.microsoft.com/#mscorlib/system/threading/ThreadLocal.cs,
b0c23fc7e6f66cf4
3:https://referencesource.microsoft.com/#mscorlib/system/threadstaticattribute.cs,
14e92e6a6cd64604
4:https://www.cnblogs.com/fengzheng/p/8690253.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值