在这种情况下,ConcurrentHashMap 和 Synchronized Hash Map 哪个更好?

bal*_*_21 0 java collections multithreading hashmap concurrenthashmap

我正在编写一个使用 map 作为缓存存储的实用程序类。现在因为它将在多线程环境中使用。我想出了在执行 put 操作或 ConcurrentHashMap(使用 putIfAbsent)时使用同步哈希映射的用法,我仍然对它是否容易覆盖键值感到困惑(尽管键值在我的情况下是唯一的)并且两者都有利弊。所以我无法决定。可能还有其他一些缓存存储,我可以用于此目的,建议但我更想知道如果这是唯一的选择,将使用 CHM 或 Hashmap

在程序的评论中是 CHM 用法,我认为我已经使用了 HashMap。

public final class DateTime {

  private static final Map<CountryLanguage, Locale> localeMap = new HashMap<>();

 /*private static final Map<CountryLanguage, Locale> localeMap = new ConcurrentHashMap<>();*/

public static String getDateTime1(String pattern, LocalDateTime localDateTime, String language,
      String country) {
    if (language == null || language.isEmpty()) {
      throw new NullPointerException("Language cannot be null or empty");
    }
    CountryLanguage countryLanguage = new CountryLanguage(language, country);
    if (!localeMap.containsKey(countryLanguage)) {
      synchronized (localeMap) {
        // Putting double lock
        if (!localeMap.containsKey(countryLanguage)) {
          for (Locale locale : Locale.getAvailableLocales()) {
            if (locale.getLanguage().equals(language) && locale.getCountry().equals(country)) {
              localeMap.put(new CountryLanguage(language, country), locale);
            }
          }
        }
      }
    }
      /*for (Locale locale : Locale.getAvailableLocales()) {
        if (locale.getLanguage().equals(language) && locale.getCountry().equals(country)) {
          localeMap.putIfAbsent(new CountryLanguage(language, country), locale);
        }
    }*/
    Locale locale = localeMap.get(countryLanguage);
    if (locale == null) {
      locale = Locale.ROOT;
    }
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, locale);
    return localDateTime.format(dateTimeFormatter);
  }
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 我有一个内部类 CountryLanguage,它具有 String country,String language 作为成员变量,并且 hashCode 和 equals 方法都已被覆盖。

Edit1:我没有将整个地图制作为同步我只是在放置操作时在地图上使用同步。我正在使用双重检查来确保不存在两个键值

Ras*_*ayu 5

同步HashMap?

  1. 每个方法都使用对象级锁进行同步。所以 synchMap 上的 get 和 put 方法获取锁。
  2. 锁定整个集合是一种性能开销。当一个线程持有锁时,没有其他线程可以使用该集合。

ConcurrentHashMap:(在 JDK 5 中引入)

  1. 没有对象级别的锁定,锁定的粒度要细得多。对于 a ConcurrentHashMap,锁定可能处于哈希图存储桶级别。
  2. 较低级别锁定的效果是您可以拥有并发的读取器和写入器,这对于同步集合是不可能的。这导致更多的可扩展性。
  3. ConcurrentHashMapConcurrentModificationException 如果一个线程试图修改它而另一个线程正在迭代它,则不会抛出 a 。

所以,我推荐你ConcurrentHashMap,它不会一直阻塞所有的“cahce”。

如果您想了解更多信息HashMap 与 ConcurrentHashMap

编辑:

关于此的其他一些帖子: ConcurrentHashMap 是否完全安全?

  • @balboa_21 刚刚同步的 put 是不正确的,不,ConcurrentMap 是一个 Map,所以它不能有重复的键。 (2认同)