我在看一些遗留代码,它有以下习惯用法:
Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (myMap) {
item = myMap.get(myKey);
}
我从intelli-j的代码检查中得到的警告是:
Synchronization on local variable 'myMap'
这是合适的同步吗?为什么?
Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (someGlobalInstance.getMap()) {
item = myMap.get(myKey);
}
4条答案
按热度按时间dxpyg8gm1#
之所以将其标记为问题,是因为在局部变量上进行同步通常是个坏主意。
如果返回的对象
someGlobalInstance.getMap()
总是相同的,那么同步块实际上使用准全局对象监视,代码生成预期结果。我也同意使用同步 Package 器的建议,如果您只需要同步
get()
/put()
没有更大的同步块。但是要确保Map只能通过 Package 器访问,否则你会有另一个bug的机会。还要注意,如果
someGlobalInstance.getMap()
如果不始终返回同一个对象,则即使是第二个代码示例也无法正常工作,甚至可能比原始代码更糟,因为您可以在不同于调用对象的对象上进行同步get()
打开。enxuqcxy2#
alex是正确的,通过调用
Collections.synchronizedMap(Map)
这是一种典型的方法。但是,如果您采用这种方法,可能仍然存在需要在服务器上同步的情况Map
的锁;e、 在Map上迭代时。在您的示例中,idea的警告可以忽略,因为很明显您的局部变量:
map
是从别的地方取回的(someGlobalInstance
)而不是在方法中创建,因此可以从其他线程访问。wf82jlnq3#
我认为最好对Map使用同步 Package 器
yks3o0rb4#
我认为代码可能是合理的,这取决于getmap()方法的作用。如果它保留对一个示例的引用,而该示例必须在线程之间共享,那么这是有意义的。警告是不相关的,因为局部变量没有在本地初始化。