我在下面的班级
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才能解决我的问题? 通常,如果我在类中有多个状态,那么我应该将它们放入同步方法中,而不是使每个状态都使用2currentHashMaps?
答案 0 :(得分:2)
仅使用ConcurrentHashMap
结构不会使LRUCache
类具有线程安全性。您需要适当地控制访问权限,以便在执行多步放置/获取操作时,没有其他线程可以修改基础内容。这可以通过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的每种方法。 但是,即使所有 操作是线程安全的,检索操作不需要 锁定,并且不支持将整个表锁定在 一种防止所有访问的方法。此类可与 依赖于其线程安全性但不依赖于其线程安全性的程序中的哈希表 同步详细信息。
答案 1 :(得分:1)
我将使用ReentrantLock
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html,然后就可以同步一个块而不是整个方法。