2017-01-20 5 views
0

Как обычно, мы используем Syncronization так:на другой синхронизация класса

Class A{ 
    public void method1{ 
     syncronized(this){ 
     } 
    } 
    public void method2{ 
     syncronized(this){ 
     } 
    } 
} 

Когда-нибудь, я нашел такой код:

Class B{ 
     public void method3{ 
      syncronized(B.class){ //class level lock but lock itself 
      } 
     } 
    } 
Class C{ 
     public void method4{ 
      syncronized(B.class){/class level lock but lock other class 
      } 
     } 
    } 

Как и в класс C указывает, что использовать B. класса в качестве монитора. Предполагая наличие двух потоков t1 и t2 доступа к экземпляру класса C C1, а поток t3 доступа к экземпляру класса B B1, есть ли какой-либо эффект для включения B1 или класса B, когда t1 обращается к C1? - роль B.class, просто монитор, подобный «этому» в классе B?

+0

Я бы предположил, что это артефакт для копирования/вставки. Класс C, вероятно, был создан путем копирования класса B, его переименования и удаления B-специфического материала. – sisyphus

+0

@sisyphus № это правильный код. В качестве примера рассмотрим проблему. – lawrence

+0

Мы не «обычно» используем синхронизацию, как показано в первом коде. Ошибочно вручную синхронизировать на 'this' вместо того, чтобы сделать метод' synchronized'. Второй пример, с другой стороны, - плохое и подверженное ошибкам программирование. – Kayaman

ответ

0

Если вы видите это в производственном коде, то у вас, вероятно, есть проблемы. Однако это относительно легко понять.

Экземпляр класса B используется для синхронизации как B.method3(), так и C.method4(). Таким образом, только один поток управления одновременно может входить в любой из этих методов, независимо от того, какой экземпляр он вызывает. Другого эффекта нет, если у вас нет больше вещей, которые синхронизируются в экземпляре класса B. Это довольно дробное оружие, которое нужно использовать по этой причине - вы не можете быть уверены, что еще может быть синхронизировано на B.class, поэтому уровень сериализации, который вы получаете, не определен.

Однако, это не правильная глобальная синхронизация на JVM-уровне. Различные экземпляры B.class могут существовать в разных загрузчиках классов, поэтому вам нужно быть очень осторожными в отношении того, что вы ожидаете, если будете делать это безумие. Если вы пытаетесь защитить глобальный ресурс, к которому следует когда-либо обращаться только по одной вещи, вы можете подумать об альтернативном подходе.

С более общей точки зрения, это плохая идея создать такую ​​зависимость между B и C. Это совсем не ясно почему C должен иметь метод, синхронизированный на B.class, и поэтому со временем это причина может затеряться. Вполне возможно, что изменения в B означают, что больше не нужно (или даже подходит) для C для синхронизации по B таким образом, но вы не сможете узнать.

+0

спасибо! Я пытаюсь понять, что вы сказали – lawrence

Смежные вопросы