2014-11-07 4 views
3

У меня вопрос о Java Memory Model.Случайте до отношений в Java Memory Model

В следующем сценарии: начальный: a = 0; b = 0;

T1: 
    a = 1; 
    l.lock(); 
    b = 1; 
    l.unlock(); 

T2: 
    l.lock(); 
    read b; 
    l.unlock(); 
    read a; 

Могу ли я сказать, если значение b прочитана T2 является 1, то значение a прочитано T2 должно быть 1?

В моем понимании, что unlock в T1 флеши как значение a и b в основную память, а lock в T2 убеждается как read a и read b можете получить последнее значение.

Я прав?

Редактировать: Я просто указал, что они заблокированы на одной и той же блокировке.

+2

Что вы запираете? –

+0

@SotiriosDelimanolis, не имеет значения. В Java код будет выглядеть как 'a = 1; синхронизировано (o) {b = 1; } 'и' synchronized (o) {x = b; } y = a; 'для некоторого общего объекта' o'. – aioobe

+0

@aioobe Если бы они были «синхронизированы» на разных объектах, будет ли поведение одинаковым? –

ответ

2

Могу ли я сказать, если значение b, которое читается T2, равно 1, тогда значение прочитанного T2 должно быть 1?

Да. Это гарантировано. Операция может перемещать в синхронизированный блок, но не вне от него. См. Сообщение Джереми Мэнсонса Roach Motels and The Java Memory Model.

Это означает, что, в то время как read a может двигаться перед unlock (и вверх над read b благодаря инструкции переназначения) он никогда не может двигаться вверх над lock инструкцией T2.

То же рассуждение относится и к a = 1: Он может двигаться вниз в синхронизированный блок (и ниже b = 1 благодаря инструкции переназначения), но не прошел по unlock инструкции.

Однако, если мы переставляем инструкции, как это, они оба покрыты замком, а это значит, что если T2 читает 1 из b, то T1 уже написал 1 к b.

0

Я нахожу полезную информацию от http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html.

В чем заключается синхронизация? в разделе сказано:

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

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