Баг в мемори модел
От: StanislavK Великобритания  
Дата: 17.05.12 15:00
Оценка: 2 (1)
Вот такой вот фан:

http://stackoverflow.com/questions/10620680/why-volatile-in-java-5-doesnt-synchronize-cached-copies-of-variables-with-main

В сумме получается, что в C1 (client) happens-before не работает для volatile. Соответственно не работает код, который использует piggybacking. Например, ConcurrentHashmap#containsValue() или ConcurrentHashmap#containsKey().
Воркэруйнд — использовать C2 (server).

Теперь возникает вопрос — а нет ли там еще чего-нибудь похожего Казалось бы тривиальный кейс, странно, что не был протестивован.
Re: Баг в мемори модел
От: mazurkin http://mazurkin.info
Дата: 17.05.12 15:18
Оценка:
On 17/05/12 19:00, StanislavK wrote:

> Вот такой вот фан:

> http://stackoverflow.com/questions/10620680/why-volatile-in-java-5-doesnt-synchronize-cached-copies-of-variables-with-main

> Теперь возникает вопрос — а нет ли там еще чего-нибудь похожего Казалось бы тривиальный кейс, странно, что не был протестивован.


Все не так плохо. Судя по

http://cs.oswego.edu/pipermail/concurrency-interest/2012-May/009449.html

проблема присутствует только в клиентском режиме хот-спота. Весь
продакшн как правило на Linux/Solaris — а там только серверный режим есть.

У меня на Ubuntu x64/Oracle JDK 1.6.32 x64 не воспроизводится никак
Posted via RSDN NNTP Server 2.1 beta
Re: Баг в мемори модел
От: UDI Россия  
Дата: 17.05.12 17:01
Оценка:
Здравствуйте, StanislavK, Вы писали:

Что-то я может быть тупляю, но в спецификации языка описанного поведения HB volatile не нашел, есть похожее, но там оба поля volatile. Упоминание нашел лишь в JSR 133 FAQ, хотя в самом JSR 133 тоже нет. Вот бы они там указали, где это описано. В статье есть ссылки на JSR и JLS, но как я сказал что-то пусто. Может быть это неявное поведение.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
Re[2]: Баг в мемори модел
От: RomikT Германия  
Дата: 17.05.12 20:22
Оценка: +1
Здравствуйте, UDI, Вы писали:

UDI>Здравствуйте, StanislavK, Вы писали:


UDI>Что-то я может быть тупляю, но в спецификации языка описанного поведения HB volatile не нашел, есть похожее, но там оба поля volatile. Упоминание нашел лишь в JSR 133 FAQ, хотя в самом JSR 133 тоже нет. Вот бы они там указали, где это описано. В статье есть ссылки на JSR и JLS, но как я сказал что-то пусто. Может быть это неявное поведение.


Здесь: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4

If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

Используя два раза первое правило и один раз второе получаем требуемое.
Re[3]: Баг в мемори модел
От: UDI Россия  
Дата: 17.05.12 20:37
Оценка:
Здравствуйте, RomikT, Вы писали:

RT>If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).


Ну, дык, в одном же потоке действия, про разные никто ничего не говорит.

RT>A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.


Только для этого волатильного поля (независимо от потока) порядок определен, но на порядок чтения-записи простых полей это никак не влияет. Также порядок сохраняется для n волатильных полей. 8.3.1.4 volatile Fields.

Так что вопрос, откуда это они взяли, еще открыт.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
Re[4]: Баг в мемори модел
От: RomikT Германия  
Дата: 17.05.12 20:49
Оценка:
Здравствуйте, UDI, Вы писали:

UDI>Здравствуйте, RomikT, Вы писали:


RT>>If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).


UDI>Ну, дык, в одном же потоке действия, про разные никто ничего не говорит.


RT>>A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.


UDI>Только для этого волатильного поля (независимо от потока) порядок определен, но на порядок чтения-записи простых полей это никак не влияет. Также порядок сохраняется для n волатильных полей. 8.3.1.4 volatile Fields.


UDI>Так что вопрос, откуда это они взяли, еще открыт.


Ещё раз:
int a;
volatile int b;

void inThreadA() {
  a = 1; // action1 (write to a)
  b = 1; // action2 (write to b)
}

void inThreadB() {
  if (b == 1) { // action3 (read from b)
    assert a == 1; // action 4 (read from a)
  }
}

Внутри каждого потока есть program order, по первому правилу имеем hb(action1, action2) и hb(action3, action4). Так как b volatile, то по второму правилу имеем hb(action2, action3). А из транзитивности отношения hb получаем что hb(action1, action4) несмотря на то, что a не volatile.

По приведённой же вами ссылке обе переменные должны быть volatile поскольку они читаются и пишутся в одинаковом порядке.
Re[5]: Баг в мемори модел
От: UDI Россия  
Дата: 17.05.12 21:07
Оценка:
Здравствуйте, RomikT, Вы писали:

RT>Ещё раз:

RT>
RT>int a;
RT>volatile int b;

RT>void inThreadA() {
RT>  a = 1; // action1 (write to a)
RT>  b = 1; // action2 (write to b)
RT>}

RT>void inThreadB() {
RT>  if (b == 1) { // action3 (read from b)
RT>    assert a == 1; // action 4 (read from a)
RT>  }
RT>}
RT>

RT>Внутри каждого потока есть program order, по первому правилу имеем hb(action1, action2) и hb(action3, action4). Так как b volatile, то по второму правилу имеем hb(action2, action3). А из транзитивности отношения hb получаем что hb(action1, action4) несмотря на то, что a не volatile.



У вас action2 и action3 это не одно и то же действие, и уж тем более не в одном потоке. Т.е.

If hb(x, y) and hb(y, z), then hb(x, z)


не выполняется.

RT>По приведённой же вами ссылке обе переменные должны быть volatile поскольку они читаются и пишутся в одинаковом порядке.


В примере, приведенном в спеке по моей ссылке, в ином случае (без 2-x volatile) просто никто никому ничего не гарантирует. Вопрос, почему же все-таки сообщество посчитало, что приведенное поведение гарантировано. Хотя может быть я чего-то не замечаю и вы правы. К сожалению, сейчас не могу продолжить дискуссию — очень поздно.
"Не волнуйся, голова! Теперь будет думать компьютер"
Гомер Джей Симпсон
Re[6]: Баг в мемори модел
От: RomikT Германия  
Дата: 17.05.12 21:12
Оценка: +1
Здравствуйте, UDI, Вы писали:

UDI>Здравствуйте, RomikT, Вы писали:

RT>>Внутри каждого потока есть program order, по первому правилу имеем hb(action1, action2) и hb(action3, action4). Так как b volatile, то по второму правилу имеем hb(action2, action3). А из транзитивности отношения hb получаем что hb(action1, action4) несмотря на то, что a не volatile.

UDI>У вас action2 и action3 это не одно и то же действие, и уж тем более не в одном потоке. Т.е.

UDI>

UDI>If hb(x, y) and hb(y, z), then hb(x, z)


UDI>не выполняется.


Ну ёлки-палки, используйте транзитивность два раза
hb(action1, action2) and hb(action2, action3) and hb(action3, action4) => hb(action1, action4)
Re[6]: Баг в мемори модел
От: insighter ОАЭ http://upwork.com/freelancers/~016e5772d90cce5fd1
Дата: 18.05.12 08:04
Оценка:
UDI>В примере, приведенном в спеке по моей ссылке, в ином случае (без 2-x volatile) просто никто никому ничего не гарантирует. Вопрос, почему же все-таки сообщество посчитало, что приведенное поведение гарантировано. Хотя может быть я чего-то не замечаю и вы правы. К сожалению, сейчас не могу продолжить дискуссию — очень поздно.

почему, все же четко: главный поток (main) выставляет обычную переменную "b" и волатильную "a", второй же поток (T2) ждет выставления "a", сразу после читает ее, и потом обращается к "b" — по спеке (новой 133) T2 должен увидеть все обновленные переменные до "write to a" в том числе и неволатильные.
java шараги -> enterprise галеры, банки -> highload microservices + bigdata/ml
Re[6]: Баг в мемори модел
От: StanislavK Великобритания  
Дата: 18.05.12 10:09
Оценка:
Здравствуйте, UDI, Вы писали:



UDI>У вас action2 и action3 это не одно и то же действие, и уж тем более не в одном потоке. Т.е.


На самом деле правильно замечено насчет другого потока. Но там вот какое дело:

A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).

плюс вот это:

If an action x synchronizes-with a following action y, then we also have hb(x, y).

Дают в сумме свзязь потоков и этот вывод:

A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.