我知道
synchronized(objA) {
objA.readSomething();
}
保护对象不被另一个线程修改。但是如果 objA 被声明为
class A {
public B objB;
public void readSoemthing() {
objB.readSomething();
}
}
在接下来的代码块中,另一个 thead 调用 objB.modifySomething()
?假设该线程以某种方式拥有自己对 objB
的引用。
那会安全吗?如果不是,处理它的正确方法是什么(即我不希望任何线程修改 A 内的任何内容,即使它是一个指向不同对象的字段,我也不希望该对象被修改)。
synchronized(objA) {
objA.readSomething(); // at this point antoher thread calls objB.modifySomething()
}
最佳答案
您问题的第一部分不正确。 synchronized block 仅确保在执行 synchronized block 时,没有其他线程可以进入在 objA 引用的对象上也同步的代码块。
因此任何其他线程都可能同时修改 objA
,除非所有修改 objA
的方法都是同步的。
既然你知道了,你也知道任何其他线程都可以从 objA 获取 objB 并用 objB 做任何它想做的事情,除非 objB
的所有方法也在 objA 上同步
。
这就是封装在线程安全类中至关重要的原因。所有访问(读取或写入)对象共享状态的方法都应该通过该对象的同步方法。并且共享状态永远不应该暴露给外部。
关于Java synchronized() 关键字——防止字段中引用的对象发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20076470/