Статическим членам нужны специальные блоки синхронизации? - PullRequest
4 голосов
/ 24 ноября 2008

У меня есть класс, который выглядит примерно так:

public class Test {

private static final Object someObject = new Object();

public void doSomething()
{
    synchronized (someObject) {
        System.out.println(someObject.toString());
    }
}

}

Можно ли считать объект синхронизированным или есть проблема, поскольку он является статическим членом?

Редактировать: обратите внимание, что разные потоки могут обращаться к doSomething (), и в этом случае объект должен быть доступным потокобезопасным способом.

Ответы [ 4 ]

7 голосов
/ 24 ноября 2008

Используя статический объект в качестве объекта монитора, только один поток, использующий ЛЮБОЙ экземпляр класса Test, может попасть в блок синхронизации. Если объект монитора не был статическим объектом, другие потоки, содержащие другие экземпляры класса Test, могли бы попасть в блок синхронизации.

4 голосов
/ 24 ноября 2008

Здесь someObject действует как блокировка (монитор) для всех объектов типа Test. То есть, если doSomething () вызывается в двух отдельных экземплярах Test, один из них блокируется до завершения другого. Это отличается от синхронизированного метода, который в основном эквивалентен приведенному выше коду с someObject , замененным на this .

Изменение someObject на нестатическое приведет к блокировке для каждого экземпляра. По сути, это идиома «закрытый объект блокировки», как описано в пункте 70 Effective Java .

1 голос
/ 25 ноября 2008

Обычный шаблон для получения блокировки класса, независимой от экземпляра, такой, как это, - использование самого объекта Class:

public class Test {
  public void doSomething() {
    synchronized (Test.class) {
      // something
    }
  }
}

что фактически делает синхронизированный статический метод. Конечно, если вы хотите использовать более одной блокировки, вам нужно объявить их как статические поля, как в вашем примере.

0 голосов
/ 14 декабря 2010

Что произойдет, если тестовый класс загружается с использованием разных загрузчиков классов?

...