В чем разница между синхронизированными методами и блоками? - PullRequest
8 голосов
/ 28 апреля 2010

В чем разница между synchronized методами и synchronized утверждениями ?

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

Ответы [ 5 ]

13 голосов
/ 28 апреля 2010

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

Синхронизированные блоки предпочтительнее, если они не оказываются эквивалентными всей области действия метода и / или если они блокируют нечто менее драконовское, чем экземпляр (или класс, если он статический).

8 голосов
/ 28 апреля 2010

Цитаты из JLS (включая пример):

JLS 14,19 * Заявление synchronized

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

JLS 8.4.3.6 synchronized Методы

Метод synchronized получает монитор перед его выполнением. Для метода класса (static) используется монитор, связанный с объектом Class для класса метода. Для метода экземпляра используется монитор, связанный с this (объект, для которого был вызван метод).

Это те же самые блокировки, которые могут использоваться оператором synchronized; таким образом, код:

class Test {
    int count;
    synchronized void bump() { count++; }
    static int classCount;
    static synchronized void classBump() {
        classCount++;
    }
}

имеет точно такой же эффект, как:

class BumpTest {
    int count;
    void bump() {
        synchronized (this) {
            count++;
        }
    }
    static int classCount;
    static void classBump() {
        try {
            synchronized (Class.forName("BumpTest")) {
                classCount++;
            }
        } catch (ClassNotFoundException e) {
                ...
        }
    }
}

Так чем они отличаются?

Цитата из Effective Java 2nd Edition , пункт 67: избегать чрезмерной синхронизации:

Как правило, вы должны выполнять как можно меньше работы в synchronized регионах.

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

Если ваш метод не очень прост и / или вам не нужно получить блокировку this на весь период действия метода (или блокировку объекта Class, если метод static), вы должны использовать synchronized операторы, ограничивающие синхронизацию внутри метода только тем моментом, когда он вам нужен (т. е. когда вы обращаетесь к изменяемым данным общего доступа)

4 голосов
/ 28 апреля 2010

Метод synchronized - это метод, тело которого автоматически инкапсулируется в блоке synchronized.

Таким образом, это равно:

public void foo()
{
    synchronized (this)
    {
        bar();
    }
}

public synchronized void foo()
{
    bar();
}
3 голосов
/ 28 апреля 2010
Метод

synchronized on заблокирован для объекта this. Это равно synchronized (this) {}

Стандартный synchronized заблокирован на указанном объекте / мониторе. С помощью synchronized (***) {} вы можете выбрать объект для блокировки.

2 голосов
/ 28 апреля 2010

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

...