定义
ThreadLocal 提供 线程局部变量;一个线程局部变量在多个线程中分别有独立的值(副本)
产生背景
用于多线程场景,避免 一致性问题
一致性问题:
- 发生在多个主体对同一份数据无法达成共识。
- 包括:分布式一致性问题、并发问题等。
- 特点:场景多、问题复杂、难以察觉 — 需要严密的思考甚至数学论证。
一致性问题解决办法:
- 排队(例如:锁 synchronized、互斥量、管程、屏障等)
- 投票(例如:Paxos,Raft 等)
- 避免(例如:ThreadLocal 等 空间换时间的方式)
实现细节
ThreadLocal
模型:
使用场景
线程资源持有
在一个用户一个线程的情况下, 用户数据使用 ThreadLocal 存储, 其他程序模块可以方便地拿到分配给当前线程的用户的数据, 全局获取, 减少编程难度.
线程资源一致性
以 JDBC 为例, 一个事务分为多个 Part, 它们在同一个线程中 (如 Spring 响应池中分配的一个线程) 请求获取一个数据库连接, 将会得到同一个 JDBC 连接. 这样的好处是一个 JDBC 连接维护了事务的状态, 相同事务多次获取连接可以拿到同一个 JDBC 连接.ThreadLocal 帮助需要保持线程一致的资源 (如数据库事务) 维护一致性, 降低编程难度.
线程安全
在以前 C 语言中常用 setLastError()
和getLastError()
, 多线程下就需要 ThreadLocal 保证一致性.ThreadLocal 帮助只考虑了单线程的程序库, 无缝向多线程场景迁移.
分布式计算
将计算任务分给不同的线程, 用 ThreadLocal
存储本线程的计算结果, 然后再汇总.