使用ConcurrentHashMap进行多线程处理

时间:2015-08-08 15:32:26

标签: java

我尝试使用具有以下行为的ConcurrentHashMap创建方法。

  1. 阅读无锁
  2. 写锁定
  3. 在写作之前
    1. 阅读以查看记录是否存在,
    2. 如果它仍然不存在,请保存到数据库并添加记录到地图。
    3. 如果记录存在于上一次写入,则只返回记录。
  4. 我的想法。

    private Object lock1 = new Object();
    
    private ConcurrentHashMap<String, Object> productMap;
    
    private Object getProductMap(String name) {
    
        if (productMap.isEmpty()) {
            productMap = new ConcurrentHashMap<>();
        }
    
        if (productMap.containsKey(name)) {
            return productMap.get(name);
        }
    
        synchronized (lock1) {
            if (productMap.containsKey(name)) {
                return productMap.get(name);
            } else {
                Product product = new Product(name);
                session.save(product);
                productMap.putIfAbsent(name, product);
            }
        }
    
    }
    

    有人可以帮我理解这是否是正确的方法?

1 个答案:

答案 0 :(得分:1)

这里有几个错误。

  • 如果productMap无法保证初始化,那么您在此方法的第一个声明中会得到NPE
  • 如果地图为空,则该方法不保证返回任何内容。
  • 该方法不会在所有路径上返回。
  • 该方法名称不详,不必要;你试图效仿putIfAbsent哪一半完成你的目标。
  • 您也不需要进行任何同步; ConcurrentHashMap对于您的目的而言是线程安全的。

如果我要改写这个,我会做一些不同的事情:

  • 急切地实例化ConcurrentHashMap
  • 将其绑定到ConcurrentMap而不是具体类(所以ConcurrentMap<String, Product> productMap = new ConcurrentHashMap<>();
  • 将方法重命名为putIfMissing并委托给putIfAbsent,如果结果为null,则使用一些逻辑返回我想添加的相同记录。以上绝对取决于具有定义明确的Productequals方法的 hashCode,以便new Product(name)将生成具有相同值的对象equalshashCode如果提供相同的name

  • 使用Optional来避免任何结果为putIfAbsent的NPE,并提供更容易理解的代码。

以上的片段:

public Product putIfMissing(String key) {
    Product product = new Product(key);
    Optional<Product> result =
         Optional.ofNullable(productMap.putIfAbsent(key, product));
    session.save(result.orElse(product));
    return result.orElse(product);
}
相关问题