簡體   English   中英

“同步(this)”與“synchronized((BaseClass)this)”在Java中?

[英]“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只改變編譯時類型,對對象標識沒有影響。

因此,您不必在子類中添加額外的同步。

就同​​步而言,所有三個示例都是正確的。

  1. 只有一個監視器與任何對象相關聯。
  2. this轉換為synchronized內的基類沒有任何區別。
  3. 對於同一個對象,在派生類或基類的上下文中是否調用synchronized(this)並不重要:在兩種情況下都使用相同的鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM