Подтвердить что ты не робот

Пример кода, чтобы показать, как работает синхронизированный блок Java

Я изучаю многопоточность java, мне было трудно понять, как работает синхронизированный блок:

 synchronized(Object o){
     // do something
    }

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

4b9b3361

Ответ 1

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

Подробнее: http://javarevisited.blogspot.com/2011/04/synchronization-in-java-synchronized.html#ixzz2LOWwnCjH

Посмотрите на Пример

Ответ 2

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

Простой пример:

public void synchronized method(){}  
public void synchronized staticmethod(){}
public void myMethod(){

            synchronized (this){             // synchronized keyword on block of  code
            }

}

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

synchronized void foo() {
  ...
}

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

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

Ответ 3

Внутренние блокировки и синхронизация

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

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

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

Замки в синхронизированных методах

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

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

Ответ 4

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

Ответ 5

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

Итак, синхронизируйте блок, обеспечивающий атомарность кучи операторов кода.

В отличие от того, что указано в @lucifier, синхронизация и энергозависимость не соответствуют той же цели, volatile предназначен для обеспечения того, чтобы два потока взаимодействовали друг с другом и получали максимальное значение обновления из основной памяти вместо того, чтобы получать значение из отдельного кеша .it также обеспечивает поведение "произойдет до" для выполнения.

Например, определение переменной как volatile (volatile int я = 10;), выполняющая операцию приращения (i ++;) в несинхронизированном методе, не дает такого же поведения, когда (i ++) заключен в синхронизированный блок.