变量的同步和本地副本 [英] Synchronized and local copies of variables

查看:191
本文介绍了变量的同步和本地副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看一些具有以下成语的遗留代码:

I'm looking at some legacy code which has the following idiom:

Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (myMap) {
    item = myMap.get(myKey);
}

我从Intelli-J的代码检查得到的警告是:

The warning I get from Intelli-J's code inspections is:

Synchronization on local variable 'myMap'

这是适当的同步吗?为什么?

Is this the appropriate synchronization and why?

Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (someGlobalInstance.getMap()) {
    item = myMap.get(myKey);
}


推荐答案

这被标记为一个问题是因为同步局部变量通常是一个坏主意。

The reason this is flagged as a problem is because synchronizing on local variables is usually a bad idea.

如果 someGlobalInstance.getMap返回的对象()总是相同的,然后synchronized块确实使用了那个准全局对象监视器,代码产生了预期的结果。

If the object returned by someGlobalInstance.getMap() is always the same, then the synchronized block does in fact use that quasi-global objects monitor and the code produces the expected result.

我也同意使用同步包装器的建议,如果你只需要同步 get() / put()调用并且没有任何更大的同步块。但请确保通过包装器访问地图仅 ,否则您将有另一次机会发现错误。

I also agree with the suggestion to use a synchronized wrapper, if you only need to synchronize the get()/put() calls and don't have any bigger synchronized blocks. But make sure that the Map is only accessed via the wrapper or you'll have another chance for bugs.

另请注意,如果 someGlobalInstance.getMap() 一直返回同一个对象,那么即使你的第二个代码示例也无法正常工作,它甚至可能比您的原始代码,因为您可以在不同的对象上进行同步,而不是您调用 get()的对象。

Also note that if someGlobalInstance.getMap() does not return the same object all the time, then even your second code example will not work correctly, it could even be worse than your original code since you could synchronize on a different object than the one you call get() on.

这篇关于变量的同步和本地副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆