Синхронизированный объект: код блокировки против объекта блокировки

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

synchronized(object)
{
    read object fields
}

Пока код чтения поля объекта выполняется в потоке 1, если поток 2 хочет обновить поля объекта, должен ли он ждать, пока поток 1 закончит чтение полей объекта перед обновлением (например, объект заблокирован от доступа другими потоками, в то время как выполняется блок синхронизированного кода)?


person G Vaid    schedule 01.01.2016    source источник


Ответы (3)


Нет, второй поток не будет ждать, если у него тоже нет блока synchronized для того же объекта.

synchronized(object)
{
    // read object fields
}

... in other thread:

synchronized(object)
{
    // write object fields
}
person Tamas Hegedus    schedule 01.01.2016

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

person Mureinik    schedule 01.01.2016

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

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

synchronized getField()
synchronized setField()

Теперь getField() и setField() могут безопасно вызываться несколькими потоками.

Тем не менее, использование synchronized снижает производительность, вместо этого вы можете попробовать использовать классы Locks или Atomic в java.util.concurrent.atomic, такие как AtomicInteger, AtomicBoolean или AtomicReference.

person 11thdimension    schedule 01.01.2016
comment
Не верно. Синхронизированный блок не позволяет любому другому потоку выполнять какой-либо код, синхронизированный с тем же объектом. - person user207421; 02.01.2016
comment
См. часть protected by same object monitor - person 11thdimension; 02.01.2016