Использование синхронизированного блока - PullRequest
2 голосов
/ 21 августа 2011

В чем разница или влияние между использованием синхронизированного блока, как в методе 1 и методе 2?

class A
{
  private Object lock = new Object();
  ...
  ...

  private void method1()
  {
    synchronized(A.class)
    {
      .....
    }
  }


  private void method2()
  {
    synchronized(lock)
    {
      ....
    }
  }

}

Ответы [ 5 ]

7 голосов
/ 21 августа 2011

В первом методе будут синхронизированы все потоки, которые используют ЛЮБОЙ экземпляр класса А.

Во втором методе будут синхронизированы все потоки, которые используют ЭТОТ экземпляр класса А.

3 голосов
/ 21 августа 2011

Поскольку A.class доступен для других, он является общедоступным.Если что-то еще используется для синхронизации доступа к некоторому разделу кода, тогда ваш раздел кода может быть заблокирован.Это может быть хорошо или плохо;но вы не можете контролировать его.

Использование внутреннего объекта позволяет объявить его как частный, чтобы иметь полный контроль над тем, где и когда он используется.Я предпочитаю использовать внутренний объект, который у меня есть.

1 голос
/ 21 августа 2011

Параметр синхронизированного блока необходим для возможности создания нескольких «именованных» блоков.Поэтому использование специального объекта блокировки, вероятно, более гибко: в будущем вы можете создавать lock1 и lock2.

Еще один аспект - это ожидание и уведомление.Вы можете сказать lock.wait(), а затем lock.notfify() из другого потока.В этом случае вы также можете использовать оба способа (специальный объект блокировки или A.class в качестве блокировки).

1 голос
/ 21 августа 2011

В первом случае вы синхронизируете общедоступный объект (A.class), и поэтому другие части приложения могут вызвать проблемы, поскольку они также синхронизируются на A.class.

Во втором случае вы синхронизируете объект с частной блокировкой и, таким образом, уверены, что никто другой не использует блокировку для синхронизации доступа к чему-либо еще.

Более того, как указано в других ответах, все экземпляры класса будут синхронизироваться в одной и той же блокировке с первым решением, тогда как каждый экземпляр будет иметь свою собственную блокировку со вторым решением.

Второе решение, таким образом, гораздо предпочтительнее (хотя объект блокировки должен быть окончательным).

1 голос
/ 21 августа 2011

Lock - обычное поле. Таким образом, есть один из них для каждого экземпляра «А». A.class является глобальным для всей JVM. Таким образом, два блока имеют совершенно разную семантику. Версия с блокировкой говорит: «В этом блоке может быть только один поток для этого экземпляра из A». В версии с A.class сказано, что в этом блоке может быть только один поток для любого экземпляра из A.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...