Java: Что, во всяком случае, заблокировано синхронизированными методами, кроме объекта, которому они принадлежат? - PullRequest
5 голосов
/ 04 марта 2009

Теперь я не уверен, что это глупый вопрос, пожалуйста, потерпите меня, если это так.

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

// a and b are some objects that implement Runnable
// they both reference the same third object
a.ref = c;
b.ref = c;

// a is run in a thread and processes some data in a loop for a long time
// the method the loop belongs to is declared synchronized
threadA = new Thread(a);
threadA.start();

a.someSyncedMethod(); // this would block ...
b.ref.someOtherSyncedMethod(); // ... but would this?
a.ref.someOtherSyncedMethod(); // ... and how about this?

Ответы [ 3 ]

10 голосов
/ 04 марта 2009

Стоит разделить понятия «замок» и «блокировка объекта». Нет реальной идеи «заблокировать объект» - есть «получение (и освобождение)» блокировки , связанной с объектом. Да, это звучит так, как будто я придираюсь - но различие важно, потому что если вы говорите о заблокированном объекте , это звучит так, как будто другие потоки не смогут что-либо изменить в объекте, пока удерживается эта блокировка .

Вместо этого это просто означает, что никакой другой поток не сможет получить такую ​​же блокировку, пока блокировка удерживается. Нет прямой связи между блокировкой и любым содержимым объекта, с которым связана блокировка.

Методы, объявленные как «синхронизированные», получают блокировку, связанную с экземпляром объекта, которому они принадлежат. Это только заставляет другие синхронизированные методы на том же объекте ожидать и синхронизированные операторы, которые явно синхронизируются на нем.

Лично мне не нравятся синхронизированные методы - мне нравится делать это более понятным, явно синхронизируя переменную-член (private, final), которая используется только для синхронизации.

1 голос
/ 04 марта 2009
a.someSyncedMethod(); // this would block ...

Только если вы помечаете либо метод запуска синхронизированным, либо код запуска ThreadA в синхронизированных методах.

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

Также сам класс владеет монитором для статических методов.

0 голосов
/ 04 марта 2009

Значение слова «блокировка» (фактически этот вариант называется монитором) является полностью условным, ограничения доступа не применяются.

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

...