Witaj Amigo!
Jest taki obszerny temat o nazwie Java Memory Model. W zasadzie nie musisz jeszcze tego wiedzieć, ale usłyszenie o tym będzie przydatne.
Aby wyeliminować wszystkie możliwe problemy, Java zmieniła sposób działania pamięci. Teraz nie tylko pamięć jest podzielona na lokalną pamięć podręczną wątków i globalną, ale mechanizm stał się jeszcze lepszy.
- I mocniej!
Tak, lepiej i mocniej. To jest jak samolot. Latanie samolotem jest lepsze niż chodzenie, ale trudniejsze. Postaram się wyjaśnić Ci nową sytuację w bardzo uproszczony sposób.
Oto, co wyszło. Do kodu dodano mechanizm synchronizacji lokalnej pamięci wątków, nazwany „happens before” (dosłownie „stało się to wcześniej”). Wymyślono szereg reguł/warunków, po zaistnieniu których następuje synchronizacja pamięci – aktualizacja do stanu aktualnego.
Przykład:
Zamówienie | Wątek 1 | Wątek 2 |
---|---|---|
1 2 … 101 102 103 104 105 … 201 202 203 204 205 |
|
wątek czeka na zwolnienie muteksu - mutex
|
Jednym z tych warunków jest przechwycenie uwolnionego muteksu. Jeśli mutex został zwolniony i ponownie pozyskany, pamięć zostanie zsynchronizowana przed jej pozyskaniem. Wątek 2 zobaczy „najnowsze” wartości x i y, nawet jeśli nie są one zadeklarowane jako ulotne.
- Jakie interesujące. I wiele takich warunków?
Wystarczy, oto kilka warunków synchronizacji pamięci:
- W ramach jednego wątku każde polecenie dzieje się przed (czytaj „dzieje się przed”) każda operacja, która następuje po nim w kodzie źródłowym.
- Zwolnienie blokady (odblokowania) następuje przed przejęciem tej samej blokady (blokady).
- Wyjście z zsynchronizowanego bloku/metody następuje przed wejściem do zsynchronizowanego bloku/metody na tym samym monitorze.
- Zapisywanie niestabilnego pola ma miejsce przed odczytaniem tego samego niestabilnego pola.
- Zakończenie działania metody run instancji klasy Thread następuje przed zakończeniem działania metody join() lub zwróceniem przez metodę isAlive() wartości false instancji tego samego wątku.
- Wywołanie metody start() instancji klasy Thread następuje przed uruchomieniem metody run() instancji tego samego wątku.
- Zakończenie działania konstruktora następuje przed rozpoczęciem metody finalize() tej klasy
- Wywołanie metody przerwania () w wątku dzieje się przed wątkiem, gdy wątek wykrył, że dana metoda została wywołana, albo przez zgłoszenie wyjątku InterruptedException, albo przy użyciu metod isInterrupted() lub interrupted()
- Tj. wszystko jest trochę bardziej skomplikowane niż myślałem?
Tak, to trochę trudniejsze...
Dziękuję Rysiu, pomyślę o tym.
- Nie przejmuj się tym zbytnio. Nadejdzie czas, wszystko zrozumiesz. Na razie lepiej jest zrozumieć podstawy niż zagłębiać się w tajniki wewnętrznego działania maszyny Java.
— O_o. M-tak. Niektórych rzeczy lepiej nie wiedzieć.
GO TO FULL VERSION