synchronized块中的synchronized类变量

时间:2017-09-21 17:31:35

标签: java multithreading collections thread-safety

我正在查看一些包含synchronized块的api代码,在这个块中有一个带有默认hashmap对象的同步Map;

这是正确的方法吗?

为什么地图与默认的hashmap同步,又在synchronized块中使用了这个类变量?

会导致内存泄漏吗?

public class Foo
{
  static Map synchronizedMap = Collections.synchronizedMap(new HashMap());

  public static String insertValue(String value)
   {
    String key = getKey(value);
        if(!synchronizedMap.containsKey(key))
        {
           synchronized (Foo.class) {
              synchronizedMap.put(key,"somevalue");
            }
         }
        return key; 
    }


   private static String getKey(String value)
   {
     return value+"::"+"1234";
   }

  public static boolean deleteValue(String value)
   {
       String key = getKey(value);
        Object obj = null;
       synchronized (Foo.class) {
        obj = synchronizedMap.remove(key);
    }
    if(obj == null)
           return false;
      return true;
   }
}

2 个答案:

答案 0 :(得分:0)

哈希映射的同步显得微不足道。由于synchronized块是类级锁,而map只是类级别对象,因此同步锁提供的锁定就足够了。 是的,这可以通过替换synchronized块和同步的hashmap并使用并发hashmap来改进。

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html

答案 1 :(得分:0)

您的代码不是线程安全的:

insertValue检查同步块外是否存在值,但内部不再存在。因此,另一个线程可以同时放入另一个值,然后由其中一个线程覆盖。

通常,ConcurrentHashMap远远优于您的实现,您应该使用它。它会使你的方法变得无足轻重:

public static String insertValue(String value) {
  final String key = getKey(value);
  map.putIfAbsent(key , "somevalue");
  return key;
}

public static boolean deleteValue(String value) {
  final String key = getKey(value);
  return (map.remove(key) != null);
}