Объект в синхронизированном коде, возвращаемый методом - PullRequest
1 голос
/ 06 октября 2019

Я хочу иметь синхронизированный блок, в котором объект для синхронизации возвращается из вызова метода:

...
synchronized( someGetMethod() ) {
// synchronized block
}
...

Есть ли предположение, что "someGetMethod" синхронизирован или только "// синхронизированный блок""section?

Заранее спасибо

Редактировать: У меня есть коллекция (Карта объектов для блокировки). «SomeGetMethod» проверяет, присутствует ли объект на карте, если нет, он добавит его и вернет, чтобы заблокировать. Из ответов ниже я понимаю, что someGetMethod может возвращать значение, которое уже есть на карте, но перед входом в синхронизированный блок переключиться на другой поток, который может удалить указанное выше значение. В результате другой поток может выполнить ту же проверку через "someGetMethod" и теперь получить другой результат. Поэтому, похоже, мне следует выполнить удаление из синхронизированного блока, есть ли лучший вариант?

Edit2:Спасибо за вашу помощь. Я нашел похожий вопрос - синхронизированный блок Java с использованием вызова метода для получения объекта синхронизации

Ответы [ 2 ]

4 голосов
/ 06 октября 2019

Это:

synchronized( someGetMethod() ) {
// synchronized block
}

совпадает с

Object obj = someGetMethod();
synchronized( obj ) {
// synchronized block
}

Так что нет, someGetMethod() не вызывается синхронизированным образом.

Если вы хотитечтобы его синхронизировать, нужно либо объявить метод синхронизированным, либо явно синхронизировать, например:

synchronized (this) {
  synchronized( someGetMethod() ) {
    // synchronized block
  }
}
3 голосов
/ 06 октября 2019

someGetMethod() - это выражение, которое оценивается до того, как монитор, связанный с результатом выражения, будет заблокирован потоком.

14.19. Синхронизированный оператор

Синхронизированный оператор выполняется сначала путем вычисления выражения. Затем:

  • Если оценка выражения завершается внезапнопо какой-то причине синхронизированный оператор завершается преждевременно по той же причине.

  • В противном случае, если значение выражения равно нулю, генерируется исключение NullPointerException.

  • В противном случае допустим, что ненулевое значение выражения равно V. Выполняющий поток блокирует монитор, связанный с V. Затем выполняется блок , и затем появляется выбор:

    • Если выполнение блока завершается нормально, то монитор разблокируется, а оператор синхронизации завершается нормально.

    • Если выполнение блока завершается внезапно дляПо любой причине монитор разблокируется, и оператор синхронизации завершается внезапно по той же причине.

YВы не можете войти в синхронизированный блок, оценить выражение, а затем посмотреть монитор, связанный с результатом. Как вы вошли в блок, не оценив его выражения в первую очередь? Какой монитор вы использовали для синхронизации someGetMethod() самой?

...