[英]“synchronized(this)” vs. “synchronized((BaseClass)this)” in Java?
這是我之前問題的繼承者, 是否可以通過同步安全地訪問此變量?
對於以下程序,
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)這個”不等於“這個”)
這個奇怪的模擬代碼來自以下現實生活中的例子,其中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()”方法中再添加一個synchronized塊,如下所示,
Class SubClassB extends SuperClassA {
public void inc() {
synchronized (this) {
c++;
}
}
public void dec() {
synchronized (this) {
super.dec();
}
}
}
但似乎這樣的附加塊並不優雅,可能是多余的!
有沒有人對這些問題有一些想法。 提前致謝。
勞倫斯
代碼是線程安全的,因為(SomeObject) this
this
是同一個對象。 強制轉換不會將對象轉換為另一個對象。
但是,代碼缺少封裝,因為它允許任何子類以不同步的方式訪問受保護的c
字段。 因此,任何子類都可以使用c++
或c--
而無需任何同步。 該領域應該是私人的。
計數器“c”是否可以訪問線程安全?
是的,它使用相同的鎖定對象。
我不確定在“dec()”方法中,SuperClassA是否將“this”引用為synchronized塊的有效對象?
是。
如果是,兩個同步塊是否會鎖定相同的“this”對象? (在我看來,“(SuperClassA)這個”不等於“這個”)
是。 即使你將實例轉換為可以轉換為(甚至是Object)的東西,它仍然會引用同一個對象。
[...]但似乎這樣的附加塊並不優雅,可能是多余的!
這是多余的。 只有在調用多個同步方法且組合效果必須為原子時,才需要進行額外同步。
在我看來,“(SuperClassA)這個”不等於“這個”
錯誤; 同步是在對象上完成的,而cast只改變編譯時類型,對對象標識沒有影響。
因此,您不必在子類中添加額外的同步。
就同步而言,所有三個示例都是正確的。
this
轉換為synchronized
內的基類沒有任何區別。 synchronized(this)
並不重要:在兩種情況下都使用相同的鎖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.