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

В Java используется ключевое слово synchronized все внутри одного объекта и потока.

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

3 ответа

Решение

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

Синхронизированный метод, который выглядит следующим образом:

synchronized void foobar() {
    doSomething();
}

На самом деле это всего лишь краткий способ написать это:

void foobar() {
    synchronized(this) {
        doSomething();
    }
}

Таким образом, любой вопрос о вызове синхронизированного метода действительно является вопросом о выполнении синхронизированного блока. Есть три вещи, которые могут произойти, когда ваш код входит synchronized(this) {...},

1) Если this Объект не заблокирован, тогда он будет заблокирован в имени вызывающего потока, поток выполнит операторы в блоке, а затем разблокирует блокировку, когда это будет сделано.

2) Если this объект уже был заблокирован вызывающим потоком, тогда поток просто выполнит операторы в блоке.

3) Если this Объект заблокирован каким-либо другим потоком, затем вызывающий поток будет ждать, пока другой поток не разблокирует его, и затем он продолжит работу, как в случае (1).

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

С одним объектом и одним потоком проблем нет.

Ваша единственная нить способна получить все блокировки, и благодаря повторному входу она может получить их несколько раз.

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

С несколькими потоками и несколькими объектами ответ таков: "это зависит от того, как написан код".

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

Другие вопросы по тегам