Próbując zrozumieć, w jaki sposób SubmissionPublisher
( kod źródłowy w Java SE 10, OpenJDK | docs ), nowa klasa dodana do Java SE w wersji 9, została zaimplementowana, natknąłem się na kilka wywołań API, VarHandle
których wcześniej nie byłem świadomy:
fullFence
, acquireFence
, releaseFence
, loadLoadFence
I storeStoreFence
.
Po przeprowadzeniu pewnych badań, szczególnie w odniesieniu do koncepcji barier / płotów pamięci (słyszałem o nich wcześniej, tak; ale nigdy ich nie użyłem, a zatem nie byłem zaznajomiony z ich semantyką), myślę, że mam podstawową wiedzę na temat tego, do czego służą . Niemniej jednak, ponieważ moje pytania mogą wynikać z nieporozumień, przede wszystkim chcę się upewnić, że dobrze to zrozumiałem:
Bariery pamięci zmieniają ograniczenia dotyczące operacji odczytu i zapisu.
Bariery pamięci można podzielić na dwie główne kategorie: jednokierunkowe i dwukierunkowe bariery pamięci, w zależności od tego, czy nakładają ograniczenia na odczyty, zapisy czy oba.
C ++ obsługuje różne bariery pamięci , jednak nie pasują one do tych dostarczonych przez
VarHandle
. Jednak niektóre z dostępnych barier pamięciVarHandle
zapewniają efekty porządkowania, które są zgodne z odpowiadającymi im barierami pamięci C ++.#fullFence
jest kompatybilny zatomic_thread_fence(memory_order_seq_cst)
#acquireFence
jest kompatybilny zatomic_thread_fence(memory_order_acquire)
#releaseFence
jest kompatybilny zatomic_thread_fence(memory_order_release)
#loadLoadFence
i#storeStoreFence
nie mają kompatybilnej części licznika C ++
Słowo „ kompatybilny” wydaje się tutaj naprawdę ważne, ponieważ semantyka wyraźnie różni się, jeśli chodzi o szczegóły. Na przykład wszystkie bariery C ++ są dwukierunkowe, podczas gdy bariery Java nie są (koniecznie).
- Większość barier pamięci ma również efekty synchronizacji. Te w szczególności zależą od zastosowanego rodzaju bariery i wcześniej wykonanych instrukcji barier w innych wątkach. Ponieważ pełne implikacje instrukcji barierowej są specyficzne dla sprzętu, pozostanę przy barierach wyższego poziomu (C ++). Na przykład w C ++ zmiany dokonane przed instrukcją bariery zwolnienia są widoczne dla wątku wykonującego instrukcję bariery nabywania .
Czy moje założenia są prawidłowe? Jeśli tak, moje pytania wynikowe to:
Czy dostępne bariery pamięci
VarHandle
powodują jakąkolwiek synchronizację pamięci?Niezależnie od tego, czy powodują synchronizację pamięci, czy nie, jakie zmiany w ograniczaniu kolejności mogą być przydatne w Javie? Model pamięci Java daje już pewne bardzo mocne gwarancje dotyczące zamawiania przy zmiennych polach, blokadach lub
VarHandle
podobnych operacjach#compareAndSet
.
Jeśli szukasz przykładu: wyżej wspomniana BufferedSubscription
klasa wewnętrzna SubmissionPublisher
(źródło połączone powyżej) ustanowiła pełne ogrodzenie w linii 1079 (funkcja growAndAdd
; ponieważ połączona witryna nie obsługuje identyfikatorów fragmentów, wystarczy CTRL + F dla tego ). Nie jest jednak dla mnie jasne, do czego służy.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.