Hashtable 为什么被称为线程安全?
查看完整题解
参考回答
直接回答
Hashtable 的常用读写方法使用同步,竞争线程需要先取得同一个表对象的监视器,才能进入这些受保护操作。这样能保护方法内部的数据结构与更新可见性。但线程安全有边界:多个调用组成的判断、计算和更新,仍需要原子方法或同一外部同步范围。
讲清原理
假设线程甲和乙都先读到计数 5,再各自写入 6;即使 get、put 分别同步,最终仍只增加一次。问题不是容器内部坏了,而是业务上的“加一”被拆开,两个线程拿到同一份旧值。
需要多个调用一起完成时,可在 table 对象上同步,并要求相关访问采用一致规则;也可选择契约明确的原子更新方法。迭代器和旧式 Enumeration 还具有各自约定,不能把方法同步延伸成遍历期间数据自动不变。
例子与易错点
Java 21 的 main 片段:
var table = new java.util.Hashtable<String, Integer>();
table.put("A", 5);
synchronized (table) {
table.put("A", table.get("A") + 1);
}
System.out.println(table.get("A"));
输出 6。示例说明锁的范围,不是并发压力测试。高并发单键更新可评估 ConcurrentHashMap;放入表中的可变值对象也需要单独保护。
相关题:第 3 题、第 19 题、第 28 题、第 45 题。
这道题,你掌握得怎么样?
掌握程度由你主动标记,阅读和收藏不会自动改变状态。