我正在查看一些包含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;
}
}
答案 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);
}