这是我上一个问题的后续问题,Is this variable being safely accessed by using synchronization?
对于下面的程序,
Class SubClassB extends SuperClassA {
protected int c;
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized ( (SuperClassA) this) {
c--;
}
}
}
计数器"c“是线程安全访问的吗?我不确定在"dec()“方法中,SuperClassA强制转换的"this”引用是否为synchronized块的有效对象?如果是,两个同步的块是否会锁定相同的"this“对象?(在我看来,"(SuperClassA) this“不等于"this")
这个奇怪的模拟代码来自下面的真实示例,其中SuperClassA是一个不应该被修改的基类,
Class SuperClassA {
protected int c;
public void dec() {
synchronized (this) {
c--;
}
}
}
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
super.dec();
}
}
在本例中,SubClassB中的"dec()“方法调用其超类的"dec()”方法,该方法执行对" this“对象的锁定,我认为该对象为"SuperClassA.this”。如果SubClassB的"inc()“方法中的锁定对象与SubClassB的"dec()”方法中的锁定对象不完全相同,那么我想知道SubClassB中继承的计数器"c“可能不会被不同的线程安全地访问。我觉得在同步块中使用"this“引用有一些不明确之处。
在真实的示例中,如果我希望SubClassB的计数器"c“是线程安全的,我是否需要在其"dec()”方法中再添加一个同步块,如下所示:
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized (this) {
super.dec();
}
}
}
但是看起来这样添加的块并不优雅,而且可能是多余的!
有没有人对这些问题有什么想法。提前谢谢。
劳伦斯
发布于 2012-01-05 22:15:03
计数器"c“是线程安全访问的吗?
是的,它正在使用相同的锁对象。
我不确定在"dec()“方法中,SuperClassA强制转换的”
“引用是不是同步块的有效对象?
是。
如果是,两个同步的块是否会锁定相同的“
”对象?(在我看来,"(SuperClassA) this“不等于"this")
是。即使您将实例强制转换为可以强制转换的对象(甚至是对象),它仍然会引用相同的对象。
...但是看起来这样添加的块并不优雅,而且可能是多余的!
这是多余的。仅当调用多个同步方法并且组合效果必须是原子的时,才需要额外的同步。
发布于 2012-01-05 22:07:57
因为(SomeObject) this
和this
是同一个对象,所以代码是线程安全的。强制转换不会将一个对象转换为另一个对象。
但是,该代码缺乏封装,因为它允许任何子类以不同步的方式访问受保护的c
字段。因此,任何子类都可以在没有任何同步的情况下使用c++
或c--
。该字段应为私有字段。
发布于 2012-01-05 22:08:15
在我看来,"(SuperClassA)
“不等于"this”
错误;同步是在对象上完成的,强制转换只会更改编译时类型,这对对象标识没有任何影响。
因此,您不必在子类中添加额外的同步。
https://stackoverflow.com/questions/8743768
复制相似问题