«синхронизировано (это)» против «синхронизировано ((BaseClass) это)» в 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» является допустимым объектом для синхронизированного блока? Если да, будут ли два синхронизированных блока блокировать один и тот же объект «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();
     }
}

В этом примере метод «dec ()» в SubClassB вызывает метод «dec ()» своего суперкласса, который выполняет блокировку объекта «this», который, как я полагаю, является «SuperClassA.this». Если заблокированный объект в методе «inc ()» SubClassB не совсем такой же, как заблокированный объект в методе «dec ()» SubClassB, то мне интересно, что унаследованный счетчик «c» в SubClassB НЕ может быть безопасно доступен для разных потоков. . Я чувствую, что есть некоторая двусмысленность в использовании ссылки "this" в синхронизированных блоках.

В реальном примере, если я хочу, чтобы счетчик «c» SubClassB был потокобезопасным, мне нужно добавить еще один синхронизированный блок в его метод «dec ()», например,

Class SubClassB extends SuperClassA {

     public void inc() {
          synchronized (this) {
               c++;
          }
     }

     public void dec() {
          synchronized (this) {
               super.dec();
          }
     }
}

Но кажется, что такой добавленный блок не выглядит элегантным и может быть лишним!

Есть ли у кого-нибудь идеи по этим вопросам? Заранее спасибо.

Лоуренс

10
задан Community 23 May 2017 в 10:08
поделиться