import scala.collection.immutable.HashMap
class MyClass {
var globalOne = HashMap[String, String]()
var globalTwo = HashMap[String, String]()
def dosync(k:String, v:String) = {
synchronized {
globalOne = globalOne.updated(k, v)
globalTwo = globalTwo.updated(k, v)
}
}
def getKey(k:String) = {
globalOne.get(k)
}
}
" getKey"当" dosync"时被阻止正在执行,因为dosync正在访问getKey正在访问的全局变量吗?
答案 0 :(得分:2)
简短的回答是:否。此外,它根本不会锁定任何全局变量。
不幸的是,Scala文档在这个主题上并不是很丰富,但您可以参考Java documentation on synchronized,因为它实际上是相同的。根据{{3}},synchronized
来自
class AnyRef extends Any {
...
def synchronized[T](body: => T): T // execute `body` in while locking `this`.
}
这意味着你的
def dosync(k: SomeType, v: OtherType):Unit = {
synchronized {
globalOne = globalOne.put(k, v)
globalTwo = globalTwo.put(k, v)
}
}
被翻译成Java与
相同public void dosync(SomeType k, OtherType v) {
synchronized(this) {
globalOne = globalOne.put(k, v)
globalTwo = globalTwo.put(k, v)
}
}
这里关键的问题是:在这种情况下,this
是什么?如果dosync
处于简单Class
中,则它是dosync
或静态object
对象的类的实例。在这两种情况下,globalOne
和globalTwo
都没有被锁定"以任何方式。而且,你仍然可以在锁定的情况下做任何你想做的事情。对象,只要你没有synchronize
该对象。虽然这没有明确禁止,但在大多数情况下,这不是你真正想要的。这正是您的代码中发生的事情。您的dosync
已在某个对象上同步,但getKey
(尽管很可能是同一this
的一部分)根本未同步,因此可以在不安全的情况下访问globalOne
办法。如果您希望它安全 - 您应该synchronize
内getKey