Instrukcja reordering & happens-before relation w Javie [duplikat]

to pytanie ma już odpowiedzi tutaj : Jak rozumieć dzieje się-przed konsekwentnym (4 odpowiedzi) Zamknięty 2 lata temu.

W książce Java współbieżność w praktyce, kilka razy powiedziano nam, że instrukcje naszego programu mogą być zmieniane przez kompilator, przez JVM w czasie wykonywania, a nawet przez procesor. Powinniśmy więc założyć, że uruchamiany program nie będzie miał instrukcji wykonywanych w dokładnie takiej samej kolejności, jak podaliśmy w kodzie źródłowym.

Jednak ostatni rozdział omawiający model pamięci Java zawiera listę happens-before reguły wskazujące, które instrukcje są zachowywane przez JVM. Pierwsza z tych zasad to:

  • " reguła kolejności programu. Każda akcja w wątku dzieje się przed każdą akcją w tym wątku, która pojawia się później w kolejności programu."

Wierzę ,że "kolejność programów" odnosi się do kodu źródłowego.

Moje pytanie: zakładając tę regułę, zastanawiam się, jaką instrukcję można właściwie uporządkować.

"akcja" jest zdefiniowana następująco:

Model pamięci Java jest określony w kategoriach działań, które obejmują odczyt i zapis do zmiennych, blokady i odblokowanie monitorów oraz uruchamianie i łączenie z wątkami. JMM definiuje częściowe porządkowanie nazwane happens before dla wszystkich działań w programie. Aby zagwarantować, że wątek wykonujący akcję B może zobaczyć wyniki akcji A (niezależnie od tego, czy A i B występują w różnych wątkach), musi istnieć związek a przed A I B. W przypadku braku a dzieje się to przed zamówieniem między dwiema operacjami, JVM może dowolnie zmieniać ich kolejność.

Inne wymienione reguły porządkowe to:

  • zasada blokady monitora. Odblokowanie blokady monitora następuje przed każdą kolejną blokadą tej samej blokady monitora.
  • zmienna zmienna zmienna. Zapis do pola lotnego następuje przed każdym kolejnym odczytem tego samego pola.
  • zasada rozpoczęcia wątku. Wezwanie do wątku.start na wątku dzieje się przed każdą akcją w rozpoczęty wątek.
  • zasada zakończenia wątku. Każda akcja w wątku dzieje się zanim jakikolwiek inny wątek wykryje, że wątek został zakończony, albo przez pomyślny powrót z wątku.Dołącz lub przez wątek.isAlive zwraca false.
  • zasada przerwania. Wątek wywołujący przerwanie na innym wątku dzieje się zanim przerwany wątek wykryje przerwanie (albo przez wyrzucenie InterruptedException, albo wywołanie jest przerwane lub przerwane).
  • reguła Finalizera. Koniec a konstruktor dla obiektu dzieje się przed rozpoczęciem finalizatora dla tego obiektu.
  • przechodniość. Jeśli A dzieje się przed B, A B dzieje się przed C, to a dzieje się przed C.
Author: assylias, 2013-04-25

1 answers

Kluczowym punktem reguły kolejności programu jest: w wątku.

Wyobraź sobie ten prosty program (wszystkie zmienne początkowo 0):

T1:

x = 5;
y = 6;

T2:

if (y == 6) System.out.println(x);

Z punktu widzenia T1, wykonanie musi być zgodne z y przypisanym po x (kolejność programu). Jednak z punktu widzenia T2 nie musi tak być i T2 może wydrukować 0.

T1 może przypisać y jako pierwsze, ponieważ 2 przypisania są niezależne i ich Zamiana nie wpływa na wykonanie T1.

Przy odpowiedniej synchronizacji, T2 zawsze wydrukuje 5 lub nic.

EDIT

Wydaje się, że źle interpretujesz znaczenie porządku programu. reguła kolejności programu sprowadza się do :

Jeśli x i y są działaniami tego samego wątku i x jest poprzedzone y w porządku programu, to hb(x, y) (tj. x happens-before y).

happens-before ma bardzo specyficzne znaczenie w JMM. W szczególności, to nie oznacza, że y=6 musi być po x=5 W T1 z perspektywy zegara ściennego. Oznacza to tylko, że sekwencja działań wykonywanych przez T1 musi być zgodna z tej kolejności. Możesz również odnieść się do JLS 17.4.5:

Należy zauważyć, że obecność związku między dwoma czynnościami nie z konieczności oznacza, że muszą one odbywać się w tej kolejności w realizacji . Jeśli zmiana kolejności daje wyniki zgodne z prawem wykonania, nie jest nielegalne.

W przykładzie, który podałem powyżej, zgodzisz się, że z perspektywy T1 (tj. w programie z pojedynczym wątkiem), {[11] } jest zgodne z y=6;x=5;, ponieważ nie odczytujesz wartości. Oświadczenie na następnej linii jest gwarantowane, W T1, aby zobaczyć te 2 działania, niezależnie od kolejności, w jakiej były wystąpili

 58
Author: assylias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-21 11:42:25