什么是ThreadLocal
ThreadLocal(线程本地存储)是多线程编程中实现线程隔离数据的机制,通过为每个线程创建独立的数据副本来避免资源竞争。Python 的 threading 模块通过 local 类实现这一特性:
- 每个线程访问 ThreadLocal 对象时,实际访问的是与该线程 ID 绑定的独立存储空间
- 底层通过字典结构维护 {线程ID: 私有数据}
- 无需加锁即可实现线程安全的数据访问
使用示例
python
from threading import Thread,local
import time
local = local()
class MyThread(Thread):
def __init__(self,name,):
super().__init__()
self.name = name
def run(self):
print("{} is running".format(self.name))
# 获取当前线程的变量
print(f"{self.name} 获取当前线程的变量{local.__dict__}")
# 设置当前线程的变量
local.name = "{}".format(self.name)
print(f"{self.name} 设置当前线程后的变量{local.__dict__}")
time.sleep(1)
if __name__ == '__main__':
# 创建一个变量
local.name = "main"
local.age = 18
# 创建线程
for i in range(3):
t = MyThread(i)
t.start()
print(f"main is {local.__dict__}")
输出:
python
0 is running
0 获取当前线程的变量{}
0 设置当前线程后的变量{'name': '0'}
1 is running
1 获取当前线程的变量{}
1 设置当前线程后的变量{'name': '1'}
2 is running
main is {'name': 'main', 'age': 18}
2 获取当前线程的变量{}
2 设置当前线程后的变量{'name': '2'}
进程已结束,退出代码为 0
总结:
根据示例可以看到,每个线程的 Local 都是线程私有的,互不影响。
与Java中的ThreadLocal 对比
相同点:都是保证每个线程之间的数据是线程私有的,相互隔离。
不同点:主要是体现在实现的细节上。如下面表格所示:
特性 | Python | Java |
---|---|---|
实现机制 | 基于线程ID的字典映射 | Thread对象维护内部Map |
垃圾回收 | 自动清理线程退出后的数据 | 需手动调用remove() |
协程支持 | 需使用contextvars | Java 19之前无原生支持,Java 19之后支持虚拟线程(协程的一种实现) |
继承性 | 子线程不继承父线程数据 | InheritableThreadLocal |
泛型支持 | 动态类型 | 强类型泛型 |
注意:以上是根据我自己的了解进行总结的,如果有不对的地方,还请道友指出。谢谢