首页 > 解决方案 > 如何使具有多个状态的类作为线程安全?

问题描述

我有以下课程

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 吗?

标签: javamultithreadinghashmapthread-safety

解决方案


仅仅使用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 完全可互操作。


推荐阅读