Mam pytania dotyczące użycia i znaczenia synchronized
słowa kluczowego.
- Jakie jest znaczenie
synchronized
słowa kluczowego? - Kiedy powinny być metody
synchronized
? - Co to znaczy programowo i logicznie?
java
multithreading
keyword
synchronized
Johanna
źródło
źródło
Odpowiedzi:
Słowo
synchronized
kluczowe dotyczy różnych wątków, które odczytują i zapisują te same zmienne, obiekty i zasoby. To nie jest trywialny temat w Javie, ale oto cytat z Sun:W bardzo, bardzo małym skrócie: kiedy masz dwa wątki, które czytają i zapisują w tym samym „zasobie”, powiedzmy zmienną o nazwie
foo
, musisz upewnić się, że wątki te uzyskują dostęp do zmiennej w sposób atomowy. Bezsynchronized
słowa kluczowego Twój wątek 1 może nie zobaczyć zmiany wątku 2 dokonanej nafoo
, lub, co gorsza, może zostać zmieniony tylko w połowie. Nie byłoby to logicznie oczekiwane.Ponownie jest to nietrywialny temat w Javie. Aby dowiedzieć się więcej, zapoznaj się z tematami tutaj na SO i Interwebs na temat:
Kontynuuj badanie tych tematów, dopóki nazwa „Brian Goetz” nie zostanie trwale powiązana z terminem „współbieżność” w twoim mózgu.
źródło
Cóż, myślę, że mieliśmy dość wyjaśnień teoretycznych, więc rozważ ten kod
Uwaga:
synchronized
blokuje wywołanie następnego wątku do metody test (), dopóki wykonanie poprzedniego wątku nie zostanie zakończone. Wątki mogą uzyskiwać dostęp do tej metody pojedynczo. Bezsynchronized
wszystkich wątków może uzyskać dostęp do tej metody jednocześnie.Gdy wątek wywołuje metodę synchroniczną „test” obiektu (tutaj obiekt jest instancją klasy „TheDemo”), uzyskuje blokadę tego obiektu, żaden nowy wątek nie może wywoływać ŻADNEJ metody synchronizacji tego samego obiektu, o ile poprzedni wątek który nabył blokadę, nie zwalnia blokady.
Podobnie dzieje się, gdy wywoływana jest dowolna statyczna zsynchronizowana metoda klasy. Wątek nabywa blokadę związaną z klasą (w tym przypadku dowolna niestatyczna zsynchronizowana metoda wystąpienia tej klasy może zostać wywołana przez dowolny wątek, ponieważ ta blokada poziomu obiektu jest nadal dostępna). Jakikolwiek inny wątek nie będzie mógł wywoływać żadnej statycznej zsynchronizowanej metody klasy, dopóki blokada poziomu klasy nie zostanie zwolniona przez wątek, który obecnie blokuje.
Wyjście zsynchronizowane
Wyjście bez synchronizacji
źródło
synchronized
, ale spójność pamięci jest ignorowana.synchronized
Kluczowe zapobiega jednoczesnego dostępu do bloku kodu lub obiektu przez wielu wątków. Wszystkie metodyHashtable
sąsynchronized
, więc tylko jeden wątek może wykonać dowolną z nich jednocześnie.Korzystając z innych niż
synchronized
konstrukcje, takich jakHashMap
, musisz zbudować funkcje bezpieczeństwa wątków w kodzie, aby zapobiec błędom spójności.źródło
synchronized
oznacza, że w środowisku wielowątkowym obiekt mającysynchronized
metodę (metody) / blok (y) nie pozwala dwóm wątkom na dostęp dosynchronized
metody (metod) / bloku (kodów) w tym samym czasie. Oznacza to, że jeden wątek nie może odczytać, a inny wątek go aktualizuje.Drugi wątek będzie zamiast tego czekać, aż pierwszy wątek zakończy wykonywanie. Narzutem jest szybkość, ale zaletą jest gwarantowana spójność danych.
Jeśli aplikacja jest jednowątkowa,
synchronized
bloki nie zapewniają korzyści.źródło
Słowo
synchronized
kluczowe powoduje, że wątek uzyskuje blokadę podczas wprowadzania metody, dzięki czemu tylko jeden wątek może wykonać metodę w tym samym czasie (dla danej instancji obiektu, chyba że jest to metoda statyczna).Nazywa się to często zabezpieczaniem klasy przed wątkami, ale powiedziałbym, że to eufemizm. Chociaż prawdą jest, że synchronizacja chroni wewnętrzny stan urządzenia Vector przed jego uszkodzeniem, zwykle nie pomaga to użytkownikowi.
Rozważ to:
Mimo że zastosowane metody są zsynchronizowane, ponieważ są one blokowane i odblokowywane indywidualnie, dwa niestety czasowe wątki mogą stworzyć wektor z dwoma elementami.
W rezultacie musisz także zsynchronizować kod aplikacji.
Ponieważ synchronizacja na poziomie metody jest a) kosztowna, gdy jej nie potrzebujesz, oraz b) niewystarczająca, gdy potrzebujesz synchronizacji, istnieją teraz niezsynchronizowane zamiany (ArrayList w przypadku Vector).
Niedawno wydany został pakiet współbieżności z wieloma sprytnymi narzędziami, które zajmują się problemami wielowątkowości.
źródło
Przegląd
Zsynchronizowane słowo kluczowe w Javie ma związek z bezpieczeństwem wątków, to znaczy, gdy wiele wątków odczytuje lub zapisuje tę samą zmienną.
Może się to zdarzyć bezpośrednio (poprzez dostęp do tej samej zmiennej) lub pośrednio (przy użyciu klasy, która korzysta z innej klasy, która uzyskuje dostęp do tej samej zmiennej).
Zsynchronizowane słowo kluczowe służy do zdefiniowania bloku kodu, w którym wiele wątków może uzyskać dostęp do tej samej zmiennej w bezpieczny sposób.
Głębiej
Pod względem składni
synchronized
słowo kluczowe przyjmujeObject
parametr as (zwany obiektem blokady ), po którym następuje{ block of code }
.Gdy wykonanie napotka to słowo kluczowe, bieżący wątek próbuje „zablokować / nabyć / posiadać” (wybierz) obiekt blokady i wykonać powiązany blok kodu po uzyskaniu blokady.
Wszelkie zapisy do zmiennych wewnątrz zsynchronizowanego bloku kodu są gwarantowane, aby były widoczne dla każdego innego wątku, który podobnie wykonuje kod wewnątrz zsynchronizowanego bloku kodu przy użyciu tego samego obiektu blokady .
Tylko jeden wątek na raz może przytrzymywać blokadę, w którym to czasie wszystkie inne wątki próbujące uzyskać ten sam obiekt blokady będą czekać (wstrzymają ich wykonanie). Blokada zostanie zwolniona, gdy wykonanie wyjdzie z zsynchronizowanego bloku kodu.
Zsynchronizowane metody:
Dodawanie
synchronized
kluczowe z definicją sposobu wynosi dla całego ciała przy czym sposób jest owinięta w sposób zsynchronizowany z bloku kodu obiektowego blokady istotythis
(na przykład sposoby) iClassInQuestion.getClass()
(metody Class) .- Metoda instancji to metoda, która nie ma
static
słowa kluczowego.- Metoda klasowa to metoda ze
static
słowem kluczowym.Techniczny
Bez synchronizacji nie ma gwarancji, w jakiej kolejności odczyty i zapisy mają miejsce, prawdopodobnie pozostawiając zmienną z śmieciami.
(Na przykład zmienna może kończyć się połową bitów zapisanych przez jeden wątek i połową bitów zapisanych przez inny wątek, pozostawiając zmienną w stanie, w którym żaden z wątków nie próbował pisać, ale połączony bałagan obu).
Nie wystarczy ukończyć operacji zapisu w wątku przed (czas zegara ściennego), że inny wątek ją odczyta, ponieważ sprzęt mógł buforować wartość zmiennej, a czytający wątek zobaczyłby buforowaną wartość zamiast tego, co zostało zapisane to.
Wniosek
Dlatego w przypadku Javy należy postępować zgodnie z modelem pamięci Java, aby upewnić się, że nie wystąpią błędy wątków.
Innymi słowy: używaj synchronizacji, operacji atomowych lub klas, które wykorzystują je dla Ciebie pod maską.
źródło
Pomyśl o tym jak o kołowrotku, jaki możesz znaleźć na boisku piłkarskim. Są równoległe parki ludzi, którzy chcą się dostać, ale na bramce są „zsynchronizowane”. Tylko jedna osoba na raz może się przedostać. Wszyscy, którzy chcą się przedostać, zrobią to, ale być może będą musieli poczekać, aż przejdą.
źródło
Wątki komunikują się przede wszystkim poprzez współdzielenie dostępu do pól, do których odwołują się pola odniesienia do obiektów. Ta forma komunikacji jest niezwykle wydajna, ale umożliwia dwa rodzaje błędów: błędy interferencji wątków i błędy spójności pamięci . Narzędziem niezbędnym do zapobiegania tym błędom jest synchronizacja.
Zsynchronizowane bloki lub metody zapobiegają interferencji wątków i zapewniają spójność danych. W dowolnym momencie tylko jeden wątek może uzyskać dostęp do zsynchronizowanego bloku lub metody ( sekcja krytyczna ) poprzez uzyskanie blokady. Inne wątki będą czekać na zwolnienie blokady, aby uzyskać dostęp do sekcji krytycznej .
Metody są synchronizowane po dodaniu
synchronized
do definicji lub deklaracji metody. Możesz także zsynchronizować określony blok kodu za pomocą metody.Oznacza to, że tylko jeden wątek może uzyskać dostęp do sekcji krytycznej poprzez uzyskanie blokady. O ile ten wątek nie zwolni tej blokady, wszystkie inne wątki będą musiały poczekać na uzyskanie blokady. Nie mają dostępu do wejścia do sekcji krytycznej bez blokady dostępu .
Nie da się tego zrobić za pomocą magii. Programista odpowiada za identyfikację krytycznych sekcji w aplikacji i odpowiednią ich ochronę. Java zapewnia platformę do ochrony Twojej aplikacji, ale za to, gdzie i za co należy chronić wszystkie sekcje, odpowiedzialny jest programista.
Więcej szczegółów ze strony dokumentacji Java
Wewnętrzne blokady i synchronizacja:
Z każdym obiektem jest związana wewnętrzna blokada . Zgodnie z konwencją wątek, który wymaga wyłącznego i spójnego dostępu do pól obiektu, musi uzyskać wewnętrzną blokadę obiektu przed uzyskaniem do nich dostępu, a następnie zwolnić blokadę wewnętrzną, gdy jest to zrobione.
Mówi się, że wątek jest właścicielem wewnętrznego zamka między momentem, w którym zamek uzyskał i zwolnił zamek. Tak długo, jak wątek posiada wewnętrzny zamek, żaden inny wątek nie może uzyskać tego samego zamka. Drugi wątek zostanie zablokowany podczas próby uzyskania blokady.
Synchronizacja metod ma dwa efekty :
Gdy jeden wątek wykonuje zsynchronizowaną metodę dla obiektu, wszystkie inne wątki, które wywołują metody zsynchronizowane dla tego samego bloku obiektu (zawieszają wykonywanie), dopóki pierwszy wątek nie zostanie wykonany z obiektem.
Gwarantuje to, że zmiany stanu obiektu są widoczne dla wszystkich wątków.
Poszukaj innych alternatyw dla synchronizacji w:
Unikać synchronizacji (tej) w Javie?
źródło
Synchronized normal method
odpowiednikSynchronized statement
(użyj tego)Synchronized static method
odpowiednikSynchronized statement
(klasa użytkowania)Instrukcja zsynchronizowana (przy użyciu zmiennej)
Ponieważ
synchronized
mamy zarównoSynchronized Methods
iSynchronized Statements
. JednakSynchronized Methods
jest podobny do,Synchronized Statements
dlatego musimy tylko zrozumiećSynchronized Statements
.=> Zasadniczo będziemy mieli
Oto 2, które pomogą zrozumieć
synchronized
intrinsic lock
powiązany.synchronized statement
, automatycznie pobieraintrinsic lock
dla tegosynchronized statement's
obiektu i zwalnia go, gdy metoda powróci. Tak długo, jak wątek jest właścicielemintrinsic lock
, ŻADNY inny wątek nie może uzyskać SAMEJ blokady => wątku bezpieczny.=> Gdy
thread A
wywołujesynchronized(this){// code 1}
=> cały kod bloku (klasa wewnętrzna) gdzie mająsynchronized(this)
i wszystkiesynchronized normal method
(klasa wewnętrzna) są zablokowane, ponieważ SAME blokowanie. Uruchomi się pothread A
odblokowaniu („// kod 1” zakończony).To zachowanie jest podobne do
synchronized(a variable){// code 1}
lubsynchronized(class)
.SAME LOCK => blokada (nie zależy od której metody? Lub które instrukcje?)
Używać metody zsynchronizowanej lub instrukcji zsynchronizowanych?
Wolę,
synchronized statements
ponieważ jest bardziej rozszerzalny. Przykład: w przyszłości wystarczy zsynchronizować tylko część metody. Przykład: masz 2 zsynchronizowane metody i nie mają one ze sobą żadnego związku , jednak gdy wątek uruchomi metodę, zablokuje drugą metodę (może to uniemożliwić użyciesynchronized(a variable)
).Jednak zastosowanie metody zsynchronizowanej jest proste, a kod wygląda na prosty. W przypadku niektórych klas istnieje tylko 1 metoda synchroniczna lub wszystkie metody synchronizowane w klasie, które są ze sobą powiązane => możemy użyć,
synchronized method
aby kod był krótszy i łatwiejszy do zrozumieniaUwaga
(nie ma to większego znaczenia
synchronized
, różni się między przedmiotem i klasą lub nie jest statyczny i statyczny).synchronized
lub normalny sposób lubsynchronized(this)
czysynchronized(non-static variable)
będzie zsynchronizowane bazy na każdej instancji obiektu.synchronized
lub metoda statyczna lubsynchronized(class)
czysynchronized(static variable)
będzie zsynchronizowane bazę na klasyOdniesienie
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Mam nadzieję, że to pomoże
źródło
Oto wyjaśnienie z samouczków Java .
Rozważ następujący kod:
źródło
Według mnie synchronizacja oznacza w zasadzie, że kompilator napisał monitor.enter i monitor.exit wokół twojej metody. Jako taki może być bezpieczny dla wątków, w zależności od tego, w jaki sposób jest używany (mam na myśli to, że możesz napisać obiekt za pomocą zsynchronizowanych metod, które nie są bezpieczne dla wątków w zależności od tego, co robi twoja klasa).
źródło
Brak innych odpowiedzi to jeden ważny aspekt: bariery pamięci . Synchronizacja wątków zasadniczo składa się z dwóch części: serializacji i widoczności. Radzę wszystkim, aby szukali w Google „bariery pamięci jvm”, ponieważ jest to nietrywialny i niezwykle ważny temat (jeśli zmodyfikujesz udostępnione dane, do których dostęp ma wiele wątków). Po zrobieniu tego radzę przyjrzeć się klasom pakietu java.util.concurrent, które pomagają uniknąć jawnej synchronizacji, co z kolei pomaga utrzymać proste i wydajne programy, a nawet zapobiegać impasom.
Jednym z takich przykładów jest ConcurrentLinkedDeque . W połączeniu z wzorcem poleceń pozwala tworzyć wysoce wydajne wątki robocze poprzez upychanie poleceń do współbieżnej kolejki - nie jest wymagana jawna synchronizacja, nie jest możliwe zakleszczenie, nie jest konieczne jawne sleep (), wystarczy sondować kolejkę, wywołując take ().
W skrócie: „synchronizacja pamięci” zachodzi niejawnie, gdy zaczynasz wątek, wątek kończy się, czytasz zmienną zmienną, odblokowujesz monitor (zostawiasz zsynchronizowany blok / funkcję) itp. Ta „synchronizacja” wpływa (w pewnym sensie) „spłukuje” „) wszystkie zapisy wykonane przed tym konkretnym działaniem. W przypadku wspomnianego ConcurrentLinkedDeque dokumentacja „mówi”:
To niejawne zachowanie jest dość zgubnym aspektem, ponieważ większość programistów Java bez większego doświadczenia po prostu bierze tyle, ile podano. A potem nagle potykają się o ten wątek, gdy Java nie robi tego, co „powinno” robić w środowisku produkcyjnym, w którym występuje inne obciążenie pracą - i dość trudno jest przetestować problemy z współbieżnością.
źródło
Zsynchronizowany oznacza po prostu, że wiele wątków, jeśli jest skojarzonych z jednym obiektem, może zapobiec niepoprawnemu odczytowi i zapisowi, jeśli na danym obiekcie używany jest blok synchroniczny. Aby dać ci większą jasność, weźmy przykład:
Stworzyliśmy dwa obiekty klasy MyRunnable, runnable1 jest współdzielony z wątkiem 1, a wątek 3 i runnable2 są współdzielone tylko z wątkiem 2. Teraz, gdy t1 i t3 zaczynają się bez synchronizacji, dane wyjściowe PFB sugerują, że oba wątki 1 i 3 wpływają jednocześnie na wartość var, gdzie dla wątku 2 var ma swoją pamięć.
Przy użyciu synchronizacji wątek 3 czeka na zakończenie wątku 1 we wszystkich scenariuszach. Uzyskano dwie blokady, jedną w runnable1 współdzieloną przez wątek 1 i wątek 3, a drugą w runnable2 współdzieloną tylko przez wątek 2.
źródło
zsynchronizowana prosta oznacza, że żadne dwa wątki nie mogą jednocześnie uzyskać dostępu do bloku / metody. Kiedy mówimy, że dowolny blok / metoda klasy jest zsynchronizowana, oznacza to, że tylko jeden wątek może uzyskać do nich dostęp jednocześnie. Wątek, który próbuje uzyskać do niego dostęp, najpierw blokuje ten obiekt i dopóki ta blokada nie jest dostępna, żaden inny wątek nie może uzyskać dostępu do żadnej zsynchronizowanych metod / bloków tej instancji klasy.
Uwaga: inny wątek może uzyskać dostęp do metody tego samego obiektu, który nie jest zdefiniowany jako synchronizowany. Wątek może zwolnić blokadę przez wywołanie
źródło
synchronized
blok w Javie to monitor wielowątkowy.synchronized
blok z tym samym obiektem / klasą może być wykonany tylko przez jeden wątek, wszystkie inne czekają. Może to pomóc wrace condition
sytuacji, gdy kilka wątków próbuje zaktualizować tę samą zmienną (pierwszy krok to użycievolatile
O mnie )Java 5
rozszerzonesynchronized
poprzez wsparcie [O firmiehappens-before
]Następnym krokiem jest
java.util.concurrent
lotny vs zsynchronizowany
źródło
Synchronized to słowo kluczowe w Javie, które służy do tego, aby zdarzyło się przed relacją w środowisku wielowątkowym, aby uniknąć niespójności pamięci i błędu interferencji wątku.
źródło