Вопрос-ответ

Is there an advantage to use a Synchronized Method instead of a Synchronized Block?

Есть ли преимущество в использовании синхронизированного метода вместо синхронизированного блока?

Кто-нибудь может рассказать мне о преимуществе синхронизированного метода перед синхронизированным блоком на примере?

Переведено автоматически
Ответ 1

Кто-нибудь может рассказать мне о преимуществе синхронизированного метода перед синхронизированным блоком с примером? Спасибо.


Явного преимущества использования синхронизированного метода перед блоком нет.

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

Метод:

public synchronized void method() { // blocks "this" from here.... 
...
...
...
} // to here

Блок:

public void method() { 
synchronized( this ) { // blocks "this" from here ....
....
....
....
} // to here...
}

Видите? Никакого преимущества вообще.

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

Сравнить:

// locks the whole object
...
private synchronized void someInputRelatedWork() {
...
}
private synchronized void someOutputRelatedWork() {
...
}

против.

// Using specific locks
Object inputLock = new Object();
Object outputLock = new Object();

private void someInputRelatedWork() {
synchronized(inputLock) {
...
}
}
private void someOutputRelatedWork() {
synchronized(outputLock) {
...
}
}

Также, если метод растет, вы все равно можете разделить синхронизированный раздел:

 private void method() {
... code here
... code here
... code here
synchronized( lock ) {
... very few lines of code here
}
... code here
... code here
... code here
... code here
}
Ответ 2

Единственное реальное отличие заключается в том, что синхронизированный блок может выбирать, с каким объектом он синхронизируется. Синхронизированный метод может использовать только 'this' (или соответствующий экземпляр класса для метода синхронизированного класса). Например, они семантически эквивалентны:

synchronized void foo() {
...
}

void foo() {
synchronized (this) {
...
}
}

Последний более гибкий, поскольку может конкурировать за связанную блокировку любого объекта, часто переменной-члена. Это также более детализированный метод, потому что у вас может быть параллельный код, выполняющийся до и после блока, но все еще внутри метода. Конечно, вы могли бы так же легко использовать синхронизированный метод, преобразовав параллельный код в отдельные несинхронизированные методы. Используйте тот, который делает код более понятным.

Ответ 3

Синхронизированный метод

Плюсы:


  • Ваша IDE может указывать синхронизированные методы.

  • Синтаксис более компактный.

  • Заставляет разделять синхронизированные блоки на отдельные методы.

Минусы:


  • Синхронизируется с этим и, таким образом, позволяет сторонним пользователям также синхронизироваться с ним.

  • Сложнее переместить код за пределы синхронизированного блока.

Синхронизированный блок

Плюсы:


  • Позволяет использовать закрытую переменную для блокировки и, таким образом, заставлять блокировку оставаться внутри класса.

  • Синхронизированные блоки можно найти путем поиска ссылок на переменную.

Минусы:


  • Синтаксис более сложный, что затрудняет чтение кода.


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

Ответ 4

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

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

Object writeLock = new Object();

И с этого момента каждый раз, когда производитель хочет добавить новое сообщение, мы просто фиксируем это:

synchronized(writeLock){
// do something
}

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

java multithreading concurrency