如何使具有多个状态的类作为线程安全?

时间:2018-10-25 05:34:35

标签: java multithreading hashmap thread-safety

我在下面的班级

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?

2 个答案:

答案 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,然后就可以同步一个块而不是整个方法。