java - 如何使具有多个状态的类作为线程安全?
问题描述
我有以下课程
public class LRUCache {
private HashMap<String,String> dataMap;
private HashMap<String,String> analyticsMap;
public put(String key, String value) {
dataMap.put(key, value);
String date = getCurrentDateAsString();
analyticsMap.put(key, date);
}
public get(String key) {
String date = analyticsMap.get(key);
boolean dateExpired = isDateExpired(date);
boolean value = null;
if (!dateExpired)
value = dataMap.get();
return value;
}
}
在上面的类中,我有 2 个哈希映射,它们在 get 和 put 方法中被访问。如何使此类线程安全?
我是否需要同步 get 和 put 这应该可以解决我的问题?一般来说,如果我在课堂上有超过 1 个状态,那么我应该将它们放在同步方法中,而不是让每个状态都使用 2 个 concurrentHashMaps 吗?
解决方案
仅仅使用ConcurrentHashMap
结构并不能使你的LRUCache
类线程安全。您需要正确控制访问,以便在执行多步 put/get 操作时没有其他线程可以修改底层内容。这可以通过synchronized
方法或ReentrantReadWriteLock
读/写锁来完成。
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
来自官方 Javadoc(我的亮点)https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html:
支持检索的完全并发和更新的高预期并发的哈希表。此类遵循与 Hashtable 相同的功能规范,并包含与 Hashtable 的每个方法对应的方法版本。但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且不支持以阻止所有访问的方式锁定整个表。在依赖线程安全但不依赖同步细节的程序中,此类与 Hashtable 完全可互操作。
推荐阅读
- javascript - 为什么我的 js 代码在 Laravel 8 的 Livewire 中执行点击事件时会暂停?
- amazon-web-services - 服务目录RDS MS SQL产品-如何解决亚马逊云形成异常用户
- python - Pygame:如何一次又一次地从左到右移动图像
- python-idle - 如何在 Mac 中找到 IDLE 源代码(idlelib)?
- javascript - 如何使用 joi 添加自定义错误消息?
- python - 无法使用 social-auth-app-django 断开与 Google OAuth2 的连接
- django - 在models.Model Django中使用clean方法进行验证
- python - 删除列表中包含部分单词的 Python 列表中的元素
- python - 在 python 中重塑这个错误是什么?
- nlp - NLP模型从文本中识别句子的叙述者