java - 关于“ThreadLocal”的内部设计
问题描述
刚刚研究了Java ThreadLocal的源码,有两个问题,希望大家能帮帮我!</p>
首先,为什么不只使用一个 Map
来存储所有值,而不是将映射绑定到一个线程?像这样:
public class ThreadLocal<T> {
private ConcurrentHashMap<Thread, T> threadAndVal = new ConcurrentHashMap<>();
// get value from threadAndVal.... put value to threadAndVal
}
在方法set(T value)中,我没有看到任何同步策略。这是线程安全的吗?
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value); // ⬅️Why createMap is thread safe?
}
谢谢你的帮助!</p>
解决方案
为什么不使用ConcurrentHashMap
?
主要原因是性能。使用线程安全映射比使用没有线程安全的自定义映射要慢得多。
第二个原因是,Map<Thread,T>
只要ThreadLocal
存在,a 就会保留对线程和值的引用,并且它们通常用作静态变量。
有趣的第三个原因是我可以创建一个Thread
with 被覆盖equals
并且hashCode
表现得很顽皮。
ThreadLocal.set
线程安全吗?
它不需要。第一行是:
Thread t = Thread.currentThread();
其他一切都在Thread
t
. 所有这些操作只能从那个确切的线程完成。
推荐阅读
- python - 加载模型一次,而不是每次调用图像检测脚本
- docker - 哪个是 Antlr/Antlr4 的标准 docker 镜像?
- python - 树的直径
- ios - 需要未知模块:“未定义”
- javascript - 在链接之后附加 html(以显示链接预览)
- php - php DateTime->diff 的间歇性问题
- amazon-web-services - 从 AWS 开发工具包 v3 中的本地 json 文件加载凭证?
- mongodb - Intellishell 重复文档清理
- java - 无法在 MacOS Big Sur 上安装 NetBeans
- python - 有没有一种优雅的方法可以将别名映射到连接数据文件中的真实实体名称?