Сообщения

Спецификация Java 11: 17.4.5. Порядок происходит-до (happens-before)

Изображение
Два действия могут быть упорядочены отношениями "происходит-до". Если одно действие происходит раньше другого, то первое видимо и по порядку раньше второго. Если у нас есть два действия x и y, мы пишем hb(x, y), чтобы указать, что x происходит-до y. Если x и y являются действиями одного и того же потока и x стоит перед y в программном порядке, тогда hb(x, y). От конца конструктора объекта до начала финализатора (§12.6) для этого объекта существует граница "происходит-до". Если действие x синхронизируется со следующим действием y, то у нас также есть hb(x, y). Если hb(x, y) и hb(y, z), то hb(x, z). Методы wait класса Object (§17.2.1) имеют связанные с ними действия блокировки и разблокировки; их отношения "происходит-до" определяются этими связанными действиями. Следует отметить, что наличие связи между двумя действиями не обязательно означает, что они должны происходить в таком порядке в реализации. Если изменение порядка дает результаты, соответс...

Спецификация Java 11: 17.4.4. Порядок синхронизации

Изображение
У каждого выполнения есть порядок синхронизации. Порядок синхронизации - это общий порядок всех действий синхронизации выполнения. Для каждого потока t порядок синхронизации действий синхронизации (§17.4.2) в t согласуется с программным порядком (§17.4.3) t. Действия синхронизации порождают отношение synchronized-with (синхронизирован-с) для действий, определяемое следующим образом: Действие разблокировки на мониторе m синхронизируется-со всеми последующими действиями блокировки на m (где "последующие" определены в соответствии с порядком синхронизации). Запись в изменчивую (volatile) переменную v (§8.3.1.4) синхронизируется-со всеми последующими чтениями v любым потоком (где "последующие" определены в соответствии с порядком синхронизации). Действие, запускающее поток, синхронизируется с первым действием в потоке, которое оно запускает. Запись значения по умолчанию (ноль, false или null) в каждую переменную синхронизируется с первым действием в каждом потоке....

Спецификация Java 11: 17.4.3. Программы и порядок программ

Изображение
Среди всех межпотоковых действий, выполняемых каждым потоком t, программный порядок t является общим порядком, который отражает порядок, в котором эти действия будут выполняться в соответствии с внутрипотоковой семантикой t. Набор действий является последовательным, если все действия происходят в общем порядке (порядке выполнения), который согласуется с порядком выполнения программы, и, кроме того, каждое чтение r переменной v видит значение, записанное записью w в v таким образом, что: w стоит перед r в порядке выполнения, и нет другой записи w' такой, что w предшествует w', а w' предшествует r в порядке выполнения. Последовательная согласованность - это очень надежная гарантия видимости и упорядоченности выполнения программы. В рамках последовательно согласованного выполнения существует общий порядок всех отдельных действий (таких как чтение и запись), который согласуется с порядком выполнения программы, и каждое отдельное действие является атомарным и сразу видно к...

Спецификация Java 11: 17.4.1. Общие переменные. 17.4.2. Действия

Изображение
17.4.1. Общие переменные Память, которая может быть разделена между потоками, называется общей памятью или памятью кучи (heap memory). Все поля экземпляра, статические поля и элементы массива хранятся в динамической памяти. В этой главе спецификации используется термин переменная для обозначения как полей, так и элементов массива. Локальные переменные (§14.4), формальные параметры метода (§8.4.1) и параметры обработчика исключений (§14.20) никогда не используются совместно между потоками и не зависят от модели памяти. Два доступа к одной и той же переменной (чтение или запись) считаются конфликтующими, если хотя бы одно из обращений является записью. 17.4.2. Действия Межпотоковое действие - это действие, выполняемое одним потоком, которое может быть обнаружено другим потоком или на которое может оказывать непосредственное влияние. Программа может выполнять несколько видов межпотокового действия: Чтение (обычное или не-volatile). Чтение переменной. Запись (обычная или не-volati...

Спецификация Java 11: 17.4. Модель памяти

Изображение
Модель памяти описывает, учитывая программу и трассировку выполнения этой программы, является ли трассировка выполнения законным исполнением программы. Модель памяти языка программирования Java работает, исследуя каждое чтение в трассировке выполнения и проверяя, что запись, наблюдаемая при этом чтении, действительна в соответствии с определенными правилами. Модель памяти описывает возможное поведение программы. Реализация может создавать любой код, который ей нравится, до тех пор, пока все результирующие выполнения программы дают результат, который может быть предсказан моделью памяти. Это дает разработчику большую свободу для выполнения множества преобразований кода, включая изменение порядка действий и удаление ненужной синхронизации. Пример. Неправильно синхронизированные программы могут демонстрировать неожиданное поведение Семантика языка программирования Java позволяет компиляторам и микропроцессорам выполнять оптимизацию, которая может взаимодействовать с неправильно синхр...

Спецификация Java 11: 17.3. Sleep и Yield

Изображение
Thread.sleep переводит выполняющийся в данный момент поток в спящий режим (временно прекращает выполнение) на указанную продолжительность, в зависимости от точности и аккуратности системных таймеров и планировщиков. Поток не теряет права собственности на какие-либо мониторы, и возобновление выполнения будет зависеть от планирования и доступности процессоров, на которых будет выполняться поток. Важно отметить, что ни Thread.sleep, ни Thread.yield не имеют семантики синхронизации. В частности, компилятору не нужно сбрасывать записи, кэшированные в регистрах, в общую память перед вызовом Thread.sleep или Thread.yield, а также компилятору не нужно перезагружать значения, кэшированные в регистрах, после вызова Thread.sleep или Thread.yield. Например, в следующем (сломанном) фрагменте кода предположим, что this.done является не-volatile boolean полем: while (!this.done) Thread.sleep(1000); Компилятор может прочитать поле this.done только один раз и повторно использовать кэширова...

Спецификация Java 11: 17.2.2. Уведомление. 17.2.3. Прерывания

Изображение
17.2.2. Уведомление Действия уведомления происходят при вызове методов notify и notifyAll. Пусть поток t будет потоком, выполняющим любой из этих методов для объекта m, и пусть n будет количеством действий блокировки t на m, которые не были сопоставлены действиями разблокировки. Происходит одно из следующих действий: Если n равно нулю, возникает исключение IllegalMonitorStateException. Это тот случай, когда поток t еще не имеет блокировки для цели m. Если n больше нуля и это действие уведомления, то если набор ожидания m не пуст, поток u, который является членом текущего набора ожидания m, выбирается и удаляется из набора ожидания. Нет никакой гарантии, какой поток в наборе ожидания выбран. Это удаление из набора ожидания позволяет возобновить u в действии ожидания. Обратите внимание, однако, что действия блокировки u при возобновлении не могут быть успешными до тех пор, пока t полностью не разблокирует монитор для m. Если n больше нуля и это действие notifyAll, то все пот...