T1 T2
x = 42; while (lock.trylock())
lock.lock(); lock.unlock();
assert(x == 42);
В java и c ++ модели памяти позволяют x = 42 перемещаться после блокировки (1).
И поэтому assert может потерпеть неудачу в потоке T2. Поэтому в C ++ модель памяти
они определили поведение флайлока поддельный.
Но я не нашел спецификации для trylock в модели памяти Java.
Можно утверждать, что в потоке 2 гарантированно перейти в Java. Ссылка поможет!
От Javadoc для Замок:
Неудачные операции блокировки и разблокировки, и повторный вход
операции блокировки / разблокировки, не требуют никакой памяти
эффекты синхронизации.
Если при повторной блокировке удастся получить блокировку, она синхронизируется с предыдущей блокировкой T1. Через семантику блокировки мы знаем, что не может быть предыдущей блокировки T1, когда мы входим в цикл. Таким образом, если мы войдем в цикл, связь с T1 не синхронизируется.
Если (или когда) попытка блокировки завершается неудачно, связь с T1 не синхронизируется. По крайней мере, если предположить, что trylock
сбой является «неудачной блокировкой», так как ответ от jtahlborn предлагает.
Поэтому, в любом случае, между присваиванием и утверждением нет отношения «происходит до». Таким образом, у нас есть гонка данных, и значение x может или не может быть 42.
Я ничего не могу найти явный эта Java trylock
может быть «ложным». Тем не менее, этот пример имеет поддельное поведение в Java.
Тем не менее, JavaDoc для трилока говорит
Получает блокировку, если она доступна, и немедленно возвращает с
значение истинное.
но языковая спецификация превосходит JavaDoc по моему мнению.