Синхронизация методов - PullRequest
       4

Синхронизация методов

3 голосов
/ 17 ноября 2011

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

Ответы [ 5 ]

2 голосов
/ 17 ноября 2011

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

  • Выходящий поток снимает свою блокировку.

  • Блокировка сообщает планировщику потока, что он был освобожден.

  • Планировщик потоков изменяет состояние потоков, ожидающих этой блокировки, на «выполнение».

  • Бегущие нити мчатся, чтобы захватить замок, один из них выигрывает, остальные возвращаются к ожиданию.

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

1 голос
/ 17 ноября 2011

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

вот дополнительная информация о мониторах: http://en.wikipedia.org/wiki/Monitor_(synchronization)

0 голосов
/ 16 марта 2016

Взгляните на документацию оракула страница , чтобы ясно понять концепции.

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

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

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

Javaword article by Bill Venners однозначно объясняет, что на самом деле происходит под капотами.

Twoкоды операций monitorenter и monitorexit используются для блоков синхронизации

Когда Java virtual machine встречается с monitorenter, он получает блокировку для объекта, на который ссылается objectref в стеке.Если поток уже владеет блокировкой для этого объекта, счетчик увеличивается.

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

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

Посмотрите на связанные вопросы SE:

Что означает «синхронизированный»?

Как работает синхронизация в Java?

0 голосов
/ 17 ноября 2011

Если это нестатический метод, то это эквивалентно синхронизации по this:

public synchronized void xyz() { ... }

эквивалентно

public void xyz() {
    synchronized(this) {
        ...
    }
}

Когда это статический метод, тогда онвместо этого синхронизируется по объекту класса.

0 голосов
/ 17 ноября 2011

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

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

В то же время, если поток B и поток C вызвали один и тот же синхронизированный метод, используя тот же предыдущий объект, они начнут ждатьПоток A, чтобы снять блокировку на объекте.Когда Поток A снимет блокировку с Объекта, тогда Поток B ИЛИ Поток C может начать выполняться. Нет гарантии, какой из них будет первым.Другой продолжит ждать.

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