powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Happens Before
21 сообщений из 21, страница 1 из 1
Happens Before
    #38802793
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, может кто-то просветить а то голова уже совсем не соображает под конец рабочего дня, есть два потока, которые выполняют некую последовательность действий с одним объектом, изобразил схематически:

Код: java
1.
2.
3.
4.
5.
public class C
{
  private int r;
  private int x;
}


TreadA TreadBr = 1 r = 2lockT lockTx=3 x=4unlockT unlockT

Стартуют два потока, ThreadA стартует немного раньше и захватывает lockT первым (вроде как в точке захвата происходит happens before?) ThreadB пытается захватить lockT и блочится пока ThreadA отдаст лок. ThreadA отдает лок, ThreadB - захватывает, чему равно значение переменной r (она не volatile)?
...
Рейтинг: 0 / 0
Happens Before
    #38802800
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде как TreadA в момент unlockT должен синхронизироваться с основной памятью, а ThreadB в момент захвата должен вычитать из этой памяти, изходя из этой логики значение r будет 1?
...
Рейтинг: 0 / 0
Happens Before
    #38802808
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1,

вот здесь написано

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html

, что

Commonly, a lock provides exclusive access to a shared resource: only one thread at a time can acquire the lock and all access to the shared resource requires that the lock be acquired first.

то есть, 1,

если я, правильно вас понял.
...
Рейтинг: 0 / 0
Happens Before
    #38802835
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Остаётся только чесать репу и думать какой смысл вкладывается в lockT ?
Может monitorenter? Ох уж эти пейсатели. Убить мало...
...
Рейтинг: 0 / 0
Happens Before
    #38802860
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1,

Может быть 1, может быть 2. Как повезет. У вас же нет hb-отношений, которые запрещают видеть значение 2. Точно не может быть default value (0) при условии, что нет других потоков.

P.S. HB и Main Memory не совместимы. Main Memory была только в JLS 2 (может и в JLS 1). В JLS 3 ее заменили на HB.
...
Рейтинг: 0 / 0
Happens Before
    #38802867
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maxkar +1


автор ThreadA стартует немного раньше и захватывает lockT первым
+Из того, что ThreadA стартует раньше еще не следует, что он захватит лок первым.
...
Рейтинг: 0 / 0
Happens Before
    #38802897
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtus,

Спасибо за ссылку! Там вообщем про локи, а мне бы про этот конкретный случай, который вроде как не попадает под то описание.
...
Рейтинг: 0 / 0
Happens Before
    #38802898
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonОстаётся только чесать репу и думать какой смысл вкладывается в lockT ?
Может monitorenter? Ох уж эти пейсатели. Убить мало...

Пример далекий от продакшена, не принимайте близко к сердцу :)
...
Рейтинг: 0 / 0
Happens Before
    #38802899
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maxkar,

Огромное спасибо за разъяснение, под HB вы имеете ввиду happens before? А если бы я убрал r=2, то тут был бы happens before (TheadB увидел бы что r=1)? Вообщем надо читать JLS спецификаию, а она у меня тяжело идет(
...
Рейтинг: 0 / 0
Happens Before
    #38802900
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no56892maxkar +1


автор ThreadA стартует немного раньше и захватывает lockT первым
+Из того, что ThreadA стартует раньше еще не следует, что он захватит лок первым.
Хм, интересная мысль.
...
Рейтинг: 0 / 0
Happens Before
    #38802932
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1Вроде как TreadA в момент unlockT должен синхронизироваться с основной памятью, а ThreadB в момент захвата должен вычитать из этой памяти, изходя из этой логики значение r будет 1? j.u.c.l.Lock :Memory Synchronization
All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock, as described in section 17.4 of The Java™ Language Specification:
A successful lock operation has the same memory synchronization effects as a successful Lock action.
A successful unlock operation has the same memory synchronization effects as a successful Unlock action.
Unsuccessful locking and unlocking operations, and reentrant locking/unlocking operations, do not require any memory synchronization effects.В JMM-17.4.2 указывается, что Lock/Unlock - синхронизирующие операции.
Таким образом:
1. Когда один поток захватывает блокировку, то попытка блокировки из второго потока будет неудачной и второй поток имеет право видеть любое из возможных значений.
2. Когда один поток освобождает блокировку, то и это и (теперь успешная) попытка блокировки из второго потока будут "синхронизированы по памяти", а значит второй поток будет видеть то, что установил первый.
"По моему так" (ц) Винни-Пух голосом Евгения Леонова
...
Рейтинг: 0 / 0
Happens Before
    #38803350
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovYamahaR1Вроде как TreadA в момент unlockT должен синхронизироваться с основной памятью, а ThreadB в момент захвата должен вычитать из этой памяти, изходя из этой логики значение r будет 1? j.u.c.l.Lock :Memory Synchronization
All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock, as described in section 17.4 of The Java™ Language Specification:
A successful lock operation has the same memory synchronization effects as a successful Lock action.
A successful unlock operation has the same memory synchronization effects as a successful Unlock action.
Unsuccessful locking and unlocking operations, and reentrant locking/unlocking operations, do not require any memory synchronization effects.В JMM-17.4.2 указывается, что Lock/Unlock - синхронизирующие операции.
Таким образом:
1. Когда один поток захватывает блокировку, то попытка блокировки из второго потока будет неудачной и второй поток имеет право видеть любое из возможных значений.
2. Когда один поток освобождает блокировку, то и это и (теперь успешная) попытка блокировки из второго потока будут "синхронизированы по памяти", а значит второй поток будет видеть то, что установил первый.
"По моему так" (ц) Винни-Пух голосом Евгения Леонова

Ага, спасибо за разъяснения, т.е. в момент освобождения блокировки первым потоком произойдет "синхронизация по памяти" и второй поток увидит что r была установлена в 1, но какое из двух значений он выберет никто сказать точно не может.
...
Рейтинг: 0 / 0
Happens Before
    #38803818
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Вот это сходил за хлебушком разъяснил" ...
Как-то вы очень извратили мою мысль.

Первый поток успешно захватывает блокировку на объекте j.u.c.l.Lock.
В этом потоке гарантируется:
1. Отсутствие переупорядочиваний, которые иначе могли бы сделать java- или JIT-компиляторы;
2. Вставка специальных команд, отменяющих возможные аппаратные переупорядочивания или/и отложенные записи.

Второй поток пытается захватить ту же самую блокировку, но не неудачно.
В этом случае не гарантируется ничего. В частности, если код второго потока кешировал значение какой-либо переменной в регистрах, то он не обязан перечитывать это значение из памяти.

Первый поток успешно освобождает блокировку и снова синхронизирует состояние памяти.
После этого второй поток успешно захватывает блокировку и тоже синхронизируется. Теперь он гарантированно видит всё, что изменил первый.

P.S.
1. Как и ранее - IMHO;
2. В процессе синхронизации можно получить "потерянные обновления", так что код должен быть "правильным"
...
Рейтинг: 0 / 0
Happens Before
    #38803922
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

Спасибо за ответ. Я хотел бы у вас уточнить, что значит "синхронизирует состояние памяти", записывать все свои изменения в память что бы она была видна другим потокам? Я правильно вас понимаю что вы говорите о синхронизации Shared Memory?

Basil A. SidorovВ этом случае не гарантируется ничего. В частности, если код второго потока кешировал значение какой-либо переменной в регистрах, то он не обязан перечитывать это значение из памяти.

Первый поток успешно освобождает блокировку и снова синхронизирует состояние памяти.
После этого второй поток успешно захватывает блокировку и тоже синхронизируется. Теперь он гарантированно видит всё, что изменил первый.


Вот тут, не могли бы вы разъяснить немного подробнее на моем примере. Давайте представим что второй поток не вычитывал значение r из памяти в момент неудачного захвата лока (т.е. r = 2). Первый поток освобождает блокировку, второй поток захватывает, синхронизирует и видит что r = 1. Второй поток освобождает и синхронизирует, теперь изменения второго потока r=2 становятся видны другим потокам. Поправьте плиз если где-то ошибся.
...
Рейтинг: 0 / 0
Happens Before
    #38803941
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1Второй поток освобождает и синхронизирует, теперь изменения второго потока r=2 становятся видны другим потокам. Поправьте плиз если где-то ошибся.
неправильно, может да а может и нет. Присвоение r=2 до лока, значит никаких гарантий нет. Если бы это было после лока и перед анлоком - тогда безусловно
...
Рейтинг: 0 / 0
Happens Before
    #38803951
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никYamahaR1Второй поток освобождает и синхронизирует, теперь изменения второго потока r=2 становятся видны другим потокам. Поправьте плиз если где-то ошибся.
неправильно, может да а может и нет. Присвоение r=2 до лока, значит никаких гарантий нет. Если бы это было после лока и перед анлоком - тогда безусловно

Тогда присвоение r=1 первым потоком также не видно второму потоку после освобождения лока?
...
Рейтинг: 0 / 0
Happens Before
    #38803952
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1забыл никпропущено...

неправильно, может да а может и нет. Присвоение r=2 до лока, значит никаких гарантий нет. Если бы это было после лока и перед анлоком - тогда безусловно

Тогда присвоение r=1 первым потоком также не видно второму потоку после освобождения лока?
Всмысле нет никаких гарантий что r=1 будет видно второму потоку
...
Рейтинг: 0 / 0
Happens Before
    #38804037
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1YamahaR1пропущено...


Тогда присвоение r=1 первым потоком также не видно второму потоку после освобождения лока?
Всмысле нет никаких гарантий что r=1 будет видно второму потоку

Почему нет? Перейди от абстрактного r =1 к сохранению в List, допустим у нас вначале пустой лист
Поток А ложит туда 1, поток В ложит 2. Так как переменные не volatile, то на момент lockT вторым потоком может быть три состояния листа -

только 2 - если поток В взял лок до того как взял его поток А(или А еще не выполнил put(1)
1, 2 - если поток выполнил пут(1) взял лок, отпустил и поток B сделал put(2) перед локом
2,1 - если поток В сделал put(2), зачем-то решил сбросить кэш(так как не волатайл - то он может делать это когда угодно) и заснул перед локом(допустим свичнулся). А потом поток А сделал put(1), взял и отпустил лок. Теперь если поток В будет читать лист - то там будут именно эти значения.
...
Рейтинг: 0 / 0
Happens Before
    #38804069
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1Второй поток освобождает и синхронизирует, теперь изменения второго потока r=2 становятся видны другим потокам. Поправьте плиз если где-то ошибся.Не "становятся видны", а "могут быть видны".
Потому как со всеми остальными потоками будет та же самая ерундень: пока поток не засинхронизировался - он может видеть любое допустимое значение.
Грубо говоря, если реализована некая схема блокировки, то её обязаны использовать все участники. Или схема может развалиться в любой момент. Простого "с нашей стороны все пули вылетели" - ещё недостаточно.
...
Рейтинг: 0 / 0
Happens Before
    #38804176
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YamahaR1,

Да, hb==happens-before.

Про него нужно понять очень важный момент. hb не определяет, какое значение может увидеть чтение. Оно определяет, какие значения _не может_ увидеть чтение. И определяется это как раз через тразнитивность записей. Чтобы было понятнее, нужно уточнить ваш пример.
ThreadA ThreadBr=5r=6r=1r=2lock lockunlock unlock-- a = r-- b = r-- c = r-- print(r)
Если в этом случае у вас ThreadA выполнился перед ThreadB, будет отношение hb(r=1, print(r)) (через тразнитивность отношения). Кроме того, hb(r=5, r=1) (program order в threadA). Поэтому print(r) не может видеть (при данном порядке выполнения) запись r=5. Но может видеть r=1. Аналогично внутри потока B (там просто program order) не может быть прочитано 6, но может быть прочитано 2. А вот присваивания r=1 и r=2 - равнозначны с точки зрения модели памяти. И между ними нет никакого отношения happens-before. Поэтому может быть напечатано как 1, так и 2.

Но самое интересное даже не это. А то, что a, b и c могут (чисто теоретически) иметь совершенно неочевидные значения. Например, может быть (a=1,b=2,c=1). Или, например (a=2, b=1, c=2). И это все при том, что ThreadA выполнился до ThreadB (т.е. мы можем внутри lock/unlock условие проверить, например).
...
Рейтинг: 0 / 0
Happens Before
    #38804567
YamahaR1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ухххх, спасибо вам ребята огромное, буду разбираться :)
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Happens Before
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]