Разрешает ли Java неограниченное голодание?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Разрешает ли Java неограниченное голодание?

Сообщение Anonymous »

Введение < /h3>
Рассмотрим эту программу Java: < /p>

Код: Выделить всё

public class Loop {
static volatile boolean flag;
public static void main(String[] args) {
new Thread(() -> flag = true).start();
while(!flag);
}
}
< /code>
выражено словами: есть два потока. Один поток ждет летучего логического флага 
, чтобы стать True в цикле; Другой устанавливает флаг true .
Насколько я понимаю, спецификация языка Java не гарантирует, что эта программа останавливается - см. Ниже для моих рассуждений.
Однако я не уверен, что мое понимание здесь правильно, поскольку программы, аналогичные этим, иногда представляются в качестве примеров правильной синхронизации Java. < /p>
рассуждения < /h3>
Все ссылки на JLS см. Java SE 23. Кроме того, если я ссылаюсь на чтения или записывает, не явно указав, на какую переменную они ссылаются, я имею > Для краткости, потому что эти чтения и записи являются наиболее актуальными. < /p>
§17.4 Определяет модель памяти Java (JMM) - она ​​классифицирует, какое поведение программы является действительным, а какие нет. §17.4.1 - §17.4.7. Укажите понятие достоверных выполнений ; §17.4.8. Дополнительное ограничение казней на те, которые не нарушают причинно -следственную связь; и §17.4.9 Определяет наблюдаемое поведение s программ, опираясь на действительные выполнения. Первый шаг, я считаю, что для каждого n> 0 существует достоверное выполнение данной программы, которая содержит ровно n летучие чтения, и нет внешних действий (за исключением действия выполнения введено §17.4.9). В частности, это выполнение, чьи синхронизационные действия, упорядоченные по порядку синхронизации, являются: < /p>

[*] Два потока, A и B, начало (т.е. Действие; см. §17.4.2).
b делает одну нестабильную запись значения true
[*] a делает еще одно летучие чтения, видя летучую запись, выполняемую b. < Br /> [*] Оба A и B прекращают (то есть выполните свое синтетическое последнее действие; см. §17.4.2). < /li>
< /ol>
Я считаю, что эти казни выполнить все требования для действительных казней, приведенных в §17.4.1 - §17.4.7, и, кроме того, условия для повторных причинности, приведенных в §17.4.8. Утверждая, что с математической точностью очень утомительно, поэтому я буду опустить его для краткости (этот вопрос уже слишком длинный!)

наблюдаемое поведение

< Br /> Далее, я утверждаю, что поведение, состоящее только из действий Hang < /code>, является наблюдаемым поведением данной программы. < /p>
§17.4.9 : < /p>

тки... O Должно быть подмножеством действий E, A, и должно содержать только конечное количество действий, даже если A содержит бесконечное количество действий. Кроме того, если действие y находится в o, и либо hb (x, y) или около того (x, y), то x находится в o. p>
Поведение B является допустимым поведением программы P, если и только тогда, когда B является конечным набором внешних действий и либо: < /p>
  • [...] < /li>
    Существует множество действий, таких чтобы B состоит из заветного действия плюс все внешние действия в O и для всех k ≥ | o |, Существует выполнение e of p с действиями a, и существует набор действий, такие как:

    Оба o и o 'являются подмножествами, которые выполняют требования для наборов наблюдаемых действий. < /li>
    o ⊆ o '⊆ a < /li>
    | o' | ≥ k
  • o ' - o не содержит внешних действий
< br/>
Выберите b , чтобы быть набором Singleton, содержащего только действие Hang и O , чтобы быть пустым набором. Теперь мы должны показать условия, приведенные здесь для всех k ≥ 0 .
Для любого такого данного k выберите e , чтобы быть Выполнение с ровно k считывает. Затем - это набор, по крайней мере, k actions, который содержит ровно одно внешнее действие - в частности, выполнение . Теперь выберите o ', чтобы быть без этого действия . Затем все четыре условия из §17.4.9 выполняются:
  • " /code>, который выполняет требования для наборов наблюдаемых действий ":

    Оба o и o ' являются подмножествами . < /li>
    Оба конечные: | o | = 0 и | o '| = n+x где x - постоянное количество действий за пределами n reads.
  • не содержит действий, что означает, что условие, относящееся к Hb , является вероисповеданием.
  • содержит все действия из , за исключением выполнения , и нет x такого, что hb (выполнение времени, x) , который был бы единственным способом принуждения executionTermination быть в o '.
[*] "

Код: Выделить всё

O ⊆ O' ⊆ A
"Это правда по определению O и o '.
[*]"

Код: Выделить всё

|O'| ≥ k
"это правда, потому что o ' содержит хотя бы k reads.
[*]" не содержит внешних действий «Истинно по определению o и o ' - ни один не содержит никаких внешних действий.

< H3> Поведение реальных JVMS < /h3>
I немного экспериментировал с использованием OpenJDK - в частности, Oracle Build 23+37-2369 - на машине x86_64. < /p>
Я не смог сделать настоящий OpenJDK/Oracle JDK подвеса для вариантов этой программы, пока флаг является изменчивым - даже не введя «поощрение», как вызовы в Thread :: Sleep или Thread :: setPriority . > Для получения сгенерированной сборки) как C1, так и C2 сохраняют состояние цикла не повреждены.

Код: Выделить всё

  0x00007f7f1855e950:   movzx  r8d,BYTE PTR [r10+0x70]
0x00007f7f1855e955:   mov    r11,QWORD PTR [r15+0x450]    ; ImmutableOopMap {r10=Oop }
;*ifeq {reexecute=1 rethrow=0 return_oop=0}
; - (reexecute) Loop::main@18 (line 6)
0x00007f7f1855e95c:   test   DWORD PTR [r11],eax          ;   {poll}
0x00007f7f1855e95f:   test   r8d,r8d
0x00007f7f1855e962:   je     0x00007f7f1855e950
< /code>
Единственный вариант этой программы, где OpenJdk /Oracle JDK видит, если Flag < /code> стал нелетующим. Тем не менее, это меняет вещи даже с точки зрения JMM, потому что тогда больше нет никаких HB-Edges от действия по записи до любого из чтения. На практике на практике C2 «оптимизирует» цикл в бесконечный цикл, например,: < /p>
  0x00007ffa5455e960:   mov    r10,QWORD PTR [r15+0x450]    ; ImmutableOopMap {}
;*ifeq {reexecute=1 rethrow=0 return_oop=0}
; - (reexecute) Loop::main@18 (line 6)
0x00007ffa5455e967:   test   DWORD PTR [r10],eax          ;   {poll}
0x00007ffa5455e96a:   jmp    0x00007ffa5455e960
< /code>
 Вопросы < /h2>
[list]
[*] Является ли мое понимание JLS /JMM в том, что программа выше не останавливается? Если нет, где моя ошибка? , или его вариант (до тех пор, пока флаг 
является изменчивым ), не останавливается на реальном JVM?
[/list]

Подробнее здесь: https://stackoverflow.com/questions/794 ... starvation
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»