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?
Mam pytania dotyczące użycia i znaczenia synchronized
słowa kluczowego.
synchronized
słowa kluczowego?synchronized
?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:
synchronized
metody umożliwiają prostą strategię zapobiegania zakłóceniom wątków i błędom spójności pamięci: jeśli obiekt jest widoczny dla więcej niż jednego wątku, wszystkie odczyty lub zapisy do zmiennych tego obiektu są wykonywane metodami synchronicznymi.
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. Bez synchronized
słowa kluczowego Twój wątek 1 może nie zobaczyć zmiany wątku 2 dokonanej na foo
, 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.
Cóż, myślę, że mieliśmy dość wyjaśnień teoretycznych, więc rozważ ten kod
public class SOP {
public static void print(String s) {
System.out.println(s+"\n");
}
}
public class TestThread extends Thread {
String name;
TheDemo theDemo;
public TestThread(String name,TheDemo theDemo) {
this.theDemo = theDemo;
this.name = name;
start();
}
@Override
public void run() {
theDemo.test(name);
}
}
public class TheDemo {
public synchronized void test(String name) {
for(int i=0;i<10;i++) {
SOP.print(name + " :: "+i);
try{
Thread.sleep(500);
} catch (Exception e) {
SOP.print(e.getMessage());
}
}
}
public static void main(String[] args) {
TheDemo theDemo = new TheDemo();
new TestThread("THREAD 1",theDemo);
new TestThread("THREAD 2",theDemo);
new TestThread("THREAD 3",theDemo);
}
}
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. Bez synchronized
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
THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
Wyjście bez synchronizacji
THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
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 metody Hashtable
są synchronized
, więc tylko jeden wątek może wykonać dowolną z nich jednocześnie.
Korzystając z innych niż synchronized
konstrukcje, takich jak HashMap
, musisz zbudować funkcje bezpieczeństwa wątków w kodzie, aby zapobiec błędom spójności.
synchronized
oznacza, że w środowisku wielowątkowym obiekt mający synchronized
metodę (metody) / blok (y) nie pozwala dwóm wątkom na dostęp do synchronized
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.
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:
if (vector.isEmpty()){
vector.add(data);
}
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.
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.
Pod względem składni synchronized
słowo kluczowe przyjmuje Object
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.
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 istoty this
(na przykład sposoby) i ClassInQuestion.getClass()
(metody Class) .
- Metoda instancji to metoda, która nie ma static
słowa kluczowego.
- Metoda klasowa to metoda ze static
słowem kluczowym.
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.
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ła
http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Specyfikacja języka Java®, 13.02.2015
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ą.
Co to jest zsynchronizowane słowo kluczowe?
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 .
Kiedy metody są synchronizowane?
Metody są synchronizowane po dodaniu synchronized
do definicji lub deklaracji metody. Możesz także zsynchronizować określony blok kodu za pomocą metody.
Co to znaczy pro gramatycznie i logicznie?
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:
Synchronizacja opiera się na wewnętrznej jednostce zwanej blokadą wewnętrzną lub blokadą monitora. Zamki wewnętrzne odgrywają rolę w obu aspektach synchronizacji: wymuszają wyłączny dostęp do stanu obiektu i ustanawiają relacje, które zdarzają się przed koniecznością widoczności.
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.
Gdy wątek zwalnia blokadę wewnętrzną, między tą czynnością a każdym kolejnym nabyciem tej samej blokady ustalana jest relacja „zanim nastąpi”.
Synchronizacja metod ma dwa efekty :
Po pierwsze, niemożliwe jest przeplatanie dwóch wywołań metod zsynchronizowanych dla tego samego obiektu.
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.
Po drugie, kiedy zsynchronizowana metoda kończy działanie, automatycznie ustanawia relację przed zdarzeniem z każdym kolejnym wywołaniem zsynchronizowanej metody dla tego samego obiektu.
Gwarantuje to, że zmiany stanu obiektu są widoczne dla wszystkich wątków.
Poszukaj innych alternatyw dla synchronizacji w:
Synchronized normal method
odpowiednik
Synchronized statement
(użyj tego)
class A {
public synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(this) {
// all function code
}
}
}
Synchronized static method
odpowiednik Synchronized statement
(klasa użytkowania)
class A {
public static synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(A.class) {
// all function code
}
}
}
Instrukcja zsynchronizowana (przy użyciu zmiennej)
class A {
private Object lock1 = new Object();
public void methodA() {
synchronized(lock1 ) {
// all function code
}
}
}
Ponieważ synchronized
mamy zarówno Synchronized Methods
i Synchronized Statements
. Jednak Synchronized Methods
jest podobny do, Synchronized Statements
dlatego musimy tylko zrozumieć Synchronized Statements
.
=> Zasadniczo będziemy mieli
synchronized(object or class) { // object/class use to provides the intrinsic lock
// code
}
Oto 2, które pomogą zrozumieć synchronized
intrinsic lock
powiązany.synchronized statement
, automatycznie pobiera intrinsic lock
dla tego synchronized statement's
obiektu i zwalnia go, gdy metoda powróci. Tak długo, jak wątek jest właścicielem intrinsic lock
, ŻADNY inny wątek nie może uzyskać SAMEJ blokady => wątku bezpieczny.=> Gdy thread A
wywołuje synchronized(this){// code 1}
=> cały kod bloku (klasa wewnętrzna) gdzie mają synchronized(this)
i wszystkie synchronized normal method
(klasa wewnętrzna) są zablokowane, ponieważ SAME blokowanie. Uruchomi się po thread A
odblokowaniu („// kod 1” zakończony).
To zachowanie jest podobne do synchronized(a variable){// code 1}
lub synchronized(class)
.
SAME LOCK => blokada (nie zależy od której metody? Lub które instrukcje?)
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życie synchronized(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 zrozumienia
(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 lub synchronized(this)
czy synchronized(non-static variable)
będzie zsynchronizowane bazy na każdej instancji obiektu. synchronized
lub metoda statyczna lub synchronized(class)
czy synchronized(static variable)
będzie zsynchronizowane bazę na klasyhttps://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
Oto wyjaśnienie z samouczków Java .
Rozważ następujący kod:
public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }
if
count
jest instancjąSynchronizedCounter
, wówczas synchronizacja tych metod ma dwa efekty:
- Po pierwsze, niemożliwe jest przeplatanie dwóch wywołań metod zsynchronizowanych dla tego samego obiektu. 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.
- Po drugie, kiedy zsynchronizowana metoda kończy działanie, automatycznie ustanawia relację przed zdarzeniem z każdym kolejnym wywołaniem zsynchronizowanej metody dla tego samego obiektu. Gwarantuje to, że zmiany stanu obiektu są widoczne dla wszystkich wątków.
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).
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”:
Efekty spójności pamięci: Podobnie jak w przypadku innych współbieżnych kolekcji, akcje w wątku przed umieszczeniem obiektu w ConcurrentLinkedDeque mają miejsce przed czynnościami po dostępie lub usunięciu tego elementu z ConcurrentLinkedDeque w innym wątku.
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ą.
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:
class MyRunnable implements Runnable {
int var = 10;
@Override
public void run() {
call();
}
public void call() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
var++;
System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
}
}
}
}
public class MutlipleThreadsRunnable {
public static void main(String[] args) {
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
Thread t1 = new Thread(runnable1);
t1.setName("Thread -1");
Thread t2 = new Thread(runnable2);
t2.setName("Thread -2");
Thread t3 = new Thread(runnable1);
t3.setName("Thread -3");
t1.start();
t2.start();
t3.start();
}
}
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ęć.
Without Synchronized keyword
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -2 var value 12
Current Thread Thread -2 var value 13
Current Thread Thread -2 var value 14
Current Thread Thread -1 var value 12
Current Thread Thread -3 var value 13
Current Thread Thread -3 var value 15
Current Thread Thread -1 var value 14
Current Thread Thread -1 var value 17
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 18
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.
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
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
Object.wait()
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 w race condition
sytuacji, gdy kilka wątków próbuje zaktualizować tę samą zmienną (pierwszy krok to użycie volatile
O mnie )
Java 5
rozszerzone synchronized
poprzez wsparcie [O firmie happens-before
]
Odblokowanie (zsynchronizowane wyjście bloku lub metody) monitora następuje przed każdym kolejnym zablokowaniem (zsynchronizowanym blokiem lub wejściem metody) tego samego monitora.
Następnym krokiem jest java.util.concurrent