Как строительный блок AbstractQueuedSynchronizer параллельного API не имеет ничего синхронизированного? - PullRequest
3 голосов
/ 06 июля 2019

Я пытаюсь понять на высоком уровне, как параллельный API Java построен с использованием AbstractQueuedSynchronizer в качестве строительного блока. Я не видел никакого использования synchronized, wait() + notify() в этом классе. Тогда как можно добиться многопоточного кода?

Хотя я видел unsafe операций CAS для достижения некоторой атомарности, но этого недостаточно, чтобы иметь полностью поточно-безопасный код.

1 Ответ

3 голосов
/ 06 июля 2019

Класс Unsafe не так хорошо документирован, как классы, публично предоставляемые JDK, поэтому не все гарантии, которые его методы дают, очевидны.

Однако, если вы посмотрите на последний исходный код AbstractQueuedSynchronizer, вы увидите, что теперь он использует VarHandle, методы которого хорошо документированы.Для compareAndSet документация говорит :

Атомно устанавливает значение переменной в newValue с семантикой памяти setVolatile (java.lang.Object ...), еслитекущее значение переменной, называемое значением свидетеля, == Ожидаемое значение, к которому обращается семантика памяти getVolatile (java.lang.Object ...).

Это означает, что не будетбыть в состоянии гонки, поскольку для двух параллельных потоков только один поток обновит значение, а другой потерпит неудачу.И вы получите необходимые гарантии видимости памяти.

...