Co oznacza "zsynchronizowany"?

Mam kilka pytań dotyczących użycia i znaczenia słowa kluczowego synchronized.

  • Jakie jest Znaczenie słowa kluczowego synchronized?
  • Kiedy powinny być metody synchronized?
  • Co to znaczy programowo i logicznie?
Author: user207421, 2009-07-06

17 answers

Słowo kluczowe synchronized polega na odczytywaniu i zapisywaniu różnych wątków do tych samych zmiennych, obiektów i zasobów. To nie jest trywialny temat w Javie, ale oto cytat z Sun:

synchronized metody umożliwiają proste strategia zapobiegania wątku zakłócenia i spójność pamięci błędy: jeśli obiekt jest widoczny dla więcej niż jeden wątek, wszystkie czyta lub zapis do zmiennych tego obiektu są odbywa się za pomocą metod zsynchronizowanych.

w bardzo, bardzo małe podsumowanie: Kiedy masz dwa wątki, które czytają i zapisują do tego samego "zasobu", powiedzmy zmiennej o nazwie foo, Musisz upewnić się, że te wątki uzyskują dostęp do zmiennej w sposób atomowy. Bez słowa kluczowego synchronized, Twój wątek 1 może nie zobaczyć zmiany wątku 2 do foo, lub co gorsza, może być tylko w połowie zmieniony. To nie jest to, czego logicznie oczekujesz.

Ponownie, jest to nietrywialny temat w Javie. Aby dowiedzieć się więcej, zapoznaj się z tematami na temat SO I Interwebs o:

Kontynuuj zgłębianie tych tematów, aż nazwa"Brian Goetz" na stałe połączy się z terminem"współbieżność" w twoim mózgu.

 909
Author: Stu Thompson,
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
2018-03-30 07:18:47

Myślę, że mamy dość teoretycznych wyjaśnień, 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 (), o ile wykonanie poprzedniego wątku nie jest zakończone. Wątki mogą uzyskać dostęp do tej metody pojedynczo. Bez synchronized wszystkie wątki mogą uzyskać dostęp do tej metody jednocześnie.

Gdy wątek wywoła zsynchronizowaną metodę 'test' obiektu (tutaj obiekt jest instancją klasy 'TheDemo'), uzyskuje blokadę tego obiektu, dowolnego nowy wątek nie może wywołać żadnej zsynchronizowanej metody tego samego obiektu, o ile poprzedni wątek, który nabył blokadę, nie zwalnia blokady.

Podobna rzecz dzieje się, gdy dowolna statyczna metoda zsynchronizowana klasy jest wywoływana. Wątek uzyskuje blokadę powiązaną z klasą(w tym przypadku każda niestatyczna metoda zsynchronizowana instancji tej klasy może być wywołana przez dowolny wątek, ponieważ blokada poziomu obiektu jest nadal dostępna). Żaden inny wątek nie będzie mógł wywołać żadnego statyczna metoda zsynchronizowana klasy, o ile blokada poziomu klasy nie zostanie zwolniona przez wątek, który aktualnie trzyma blokadę.

Wyjście z synchronizacją

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
 304
Author: Dheeraj Sachan,
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
2016-11-28 05:05:34

Słowo kluczowe synchronized zapobiega jednoczesnemu dostępowi do bloku kodu lub obiektu przez wiele wątków. Wszystkie metody Hashtablesynchronized, więc tylko jeden wątek może wykonać dowolną z nich na raz.

Podczas używania konstrukcji innych niżsynchronized, takich jak HashMap, musisz zbudować funkcje bezpieczeństwa wątków w kodzie, aby zapobiec błędom spójności.

 118
Author: jmort253,
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
2020-03-11 22:40:53

synchronized oznacza to, że w środowisku wielowątkowym obiekt posiadający synchronized metody/bloki nie pozwala dwóm wątkom na dostęp do synchronized metody / bloków kodu w tym samym czasie. Oznacza to, że jeden wątek nie może czytać, podczas gdy inny wątek go aktualizuje.

Drugi wątek będzie czekał, aż pierwszy wątek zakończy swoje wykonanie. Narzut to szybkość, ale zaletą jest gwarantowana spójność danych.

Jeśli aplikacja jest jednowątkowa, synchronized bloki nie zapewniają korzyści.

 82
Author: Codemwnci,
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
2016-11-17 14:01:09

Słowo kluczowe synchronized powoduje, że wątek uzyskuje blokadę podczas wprowadzania metody, tak że tylko jeden wątek może wykonać metodę w tym samym czasie (dla danej instancji obiektu, chyba że jest to metoda statyczna).

Często nazywa się to tworzeniem bezpiecznych wątków klasowych, ale powiedziałbym, że jest to eufemizm. Chociaż prawdą jest, że synchronizacja chroni wewnętrzny stan wektora przed uszkodzeniem, zwykle nie pomaga to użytkownikowi wektora.

Rozważ to:

 if (vector.isEmpty()){
     vector.add(data);
 }

Mimo że metody są zsynchronizowane, ponieważ są blokowane i odblokowywane indywidualnie, dwa niestety wątki czasowe mogą utworzyć wektor z dwoma elementami.

Więc w efekcie, trzeba zsynchronizować w kodzie aplikacji, jak również.

Ponieważ synchronizacja na poziomie metody jest a) droga, gdy jej nie potrzebujesz i B) niewystarczająca, gdy potrzebujesz synchronizacji, istnieją teraz niezsynchronizowane zamienniki (ArrayList w przypadku Vector).

Niedawno został wydany pakiet współbieżności, z wieloma sprytnymi narzędziami, które zajmują się kwestiami wielowątkowości.

 54
Author: Thilo,
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
2009-07-06 07:09:33

Przegląd

Synchronized keyword in Java ma związek z thread-safety, czyli 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 (poprzez użycie klasy, która używa innej klasy, która ma 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.

Deeper

Składnia słowo kluczowe synchronized przyjmuje Object jako parametr (nazywany obiekt 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 swój wybór) obiekt lock i wykonać powiązany blok kodu po uzyskaniu blokady.

  • Każdy zapis do zmiennych wewnątrz zsynchronizowanego bloku kodu jest gwarantowany, że będzie widoczny dla każdego innego wątku, który podobnie wykonuje kod wewnątrz zsynchronizowanego bloku kodu używając tego samego obiektu lock .

  • Blokadę może utrzymać tylko jeden wątek na raz, podczas którego wszystkie inne wątki próbujące zdobyć ten sam obiekt lock będą czekać (wstrzymać ich wykonanie). Blokada zostanie zwolniona po zakończeniu synchronizowanego bloku kodu.

Metody zsynchronizowane:

Dodanie słowa kluczowego synchronized do definicji metody jest równe całej metodzie ciało jest owinięte w zsynchronizowany blok kodu z obiektem lock będącym this (na przykład metody) iClassInQuestion.getClass() (dla metod klasowych) .

- metoda instancji jest metodą, która nie posiada słowa kluczowego static.
- metoda klasy jest metodą zawierającą słowo kluczowe static.

Techniczne

Bez synchronizacji, nie jest gwarantowane, w jakiej kolejności będą odczyty i zapisy, ewentualnie pozostawiając zmienną z śmieci.
(na przykład zmienna może skończyć się z połową bitów zapisanych przez jeden wątek i połową bitów zapisanych przez inny wątek, pozostawiając zmienną w stanie, którego żaden z wątków nie próbował napisać, ale połączonym bałaganem obu.)

Nie wystarczy wykonać operację zapisu w wątku przed odczytaniem go przez inny wątek, ponieważ sprzęt mógł buforować wartość zmiennej, a wątek odczytujący widział wartość buforowaną zamiast tego, co do niego napisano.

Podsumowanie

Tak więc w przypadku Javy, musisz postępować zgodnie z Modelem pamięci Java, aby upewnić się, że błędy wątku nie wystąpią.
Innymi słowy: używaj synchronizacji, operacji atomowych lub klas, które używają ich za ciebie pod maską.

Źródła

Http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Specyfikacja Języka Java® , 2015-02-13

 29
Author: Gima,
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
2016-06-29 14:23:45

Pomyśl o tym jak o rodzaju kołowrotu, jaki można znaleźć na boisku do piłki nożnej. Są równoległe pary ludzi, którzy chcą wejść, ale na kołowrotku są "zsynchronizowani". Tylko jedna osoba na raz może przejść. Wszyscy ci, którzy chcą przejść, zrobią to, ale będą musieli poczekać, aż będą mogli przejść.

 21
Author: paul,
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
2009-07-06 07:09:52

Co to jest zsynchronizowane słowo kluczowe?

Wątki komunikują się przede wszystkim poprzez współdzielenie dostępu do pól i obiektów, do których odnoszą się pola odniesienia. Ta forma komunikacji jest niezwykle efektywna, ale umożliwia dwa rodzaje błędów: zakłócenia wątku i błędy spójności pamięci. Narzędziem niezbędnym do zapobiegania tym błędom jest synchronizacja.

Zsynchronizowane bloki lub metody zapobiegają zakłóceniom wątku i zapewniają, że dane są konsekwentnie. 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ą zsynchronizowane?

Metody są synchronizowane po dodaniu synchronized do definicji lub deklaracji metody. Można również zsynchronizować dany blok kodu z metodą-in.

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. Jeśli ten wątek nie zwolni tej blokady, wszystkie inne wątki będą musiały poczekać na uzyskanie blokady. Nie mają dostępu do sekcji krytycznej Z out acquiring lock.

Nie da się tego zrobić za pomocą magii. Zadaniem programisty jest zidentyfikowanie sekcji krytycznej(s) w aplikacji i odpowiednie jej zabezpieczenie. Java zapewnia framework aby chronić swoją aplikację, ale gdzie i co wszystkie sekcje mają być strzeżone jest obowiązkiem programisty.

Więcej szczegółów z dokumentacji Javy Strona

Wewnętrzne blokady i synchronizacja:

Synchronizacja jest zbudowana wokół wewnętrznej jednostki znanej jako wewnętrzna blokada lub blokada monitora. Wewnętrzne blokady odgrywają rolę w obu aspektach synchronizacji: wymuszanie wyłącznego dostępu do stanu obiektu i ustanawianie dzieje się-przed relacje, które są niezbędne do widoczności.

każdy obiekt posiada wbudowany zamek. Zgodnie z konwencją, wątek, który wymaga wyłącznego i spójnego dostępu do pól obiektu, musi nabyć wewnętrzną blokadę obiektu przed uzyskaniem dostępu do nich, a następnie zwolnić wewnętrzną blokadę, gdy zostanie to wykonane z nimi.

Mówi się, że wątek jest właścicielem wewnętrznego zamka między czasem, w którym nabył zamek i zwolnił zamek. dopóki wątek posiada wewnętrzny zamek, żaden inny gwint nie może uzyskać tego samego zamka. drugi wątek zablokuje się, gdy spróbuje zdobyć blokadę.

Gdy wątek uwalnia wewnętrzny zamek, między tą akcją a każdym kolejnym nabyciem tego samego zamka zostaje nawiązana relacja happens-before.

Tworzenie metod zsynchronizowanych ma dwa efekty :

Po pierwsze, nie jest możliwe wywołanie dwóch zsynchronizowanych metod na tym samym obiekcie do przeplatać.

Gdy jeden wątek wykonuje zsynchronizowaną metodę dla obiektu, wszystkie inne wątki, które wywołują zsynchronizowane metody dla tego samego obiektu blokują (wstrzymują wykonywanie), dopóki pierwszy wątek nie zostanie wykonany z obiektem.

Po drugie, gdy zsynchronizowana metoda kończy działanie, automatycznie ustanawia relację happens-before z każdym kolejnym wywołaniem zsynchronizowanej metody dla tego samego obiektu.

To gwarantuje, że zmiany w państwie obiektu są widoczne dla wszystkich wątków.

Poszukaj innych alternatyw dla synchronizacji w:

Unikaj synchronizacji (tego) w Javie?

 16
Author: Ravindra babu,
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
2017-07-24 16:22:21

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życia)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Synchronized statement (using variable)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Dla synchronized mamy zarówno Synchronized Methods, jak i Synchronized Statements. Jednak Synchronized Methods jest podobny do Synchronized Statements, więc musimy tylko zrozumieć Synchronized Statements.

= > zasadniczo będziemy mieli

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Oto 2 myśli, które pomagają zrozumieć synchronized

  • każdy obiekt / klasa ma intrinsic lock skojarzony z nim.
  • gdy thread wywołuje synchronized statement, automatycznie przejmuje intrinsic lock dla tego synchronized statement's obiektu i zwalnia go, gdy metoda powróci. Dopóki wątek posiada intrinsic lock, żaden inny wątek nie może zdobyć tego samego lock => thread safe.

=> Gdy thread A wywołuje synchronized(this){// code 1} = > cały kod bloku (wewnątrz klasy), gdzie mają synchronized(this) i wszystkie synchronized normal method (wewnątrz klasy) są zablokowane, ponieważ jest to samo blokada. Uruchamia się po thread A odblokowaniu ("//kod 1 " zakończony).

To zachowanie jest podobne do synchronized(a variable){// code 1} lub synchronized(class).

Ta sama blokada = > blokada (nie zależy od jakiej metody? albo jakie wypowiedzi?)

Użyć metody zsynchronizowanej czy zsynchronizowanych poleceń?

Wolę synchronized statements ponieważ jest bardziej rozszerzalny. Przykład, w przyszłości potrzebujesz tylko zsynchronizowanej części metody. Na przykład, masz 2 zsynchronizowaną metodę i nie ma żadnych istotnych dla siebie, jednak gdy wątek uruchomi metodę, zablokuje inne metody (może zapobiec przez użycie synchronized(a variable)).

Jednak zastosuj metodę synchronizowaną jest prosta, a kod wygląda prosto. Dla niektórych klas istnieje tylko 1 Metoda zsynchronizowana, lub wszystkie metody zsynchronizowane w klasie w zależności od siebie = > możemy użyć synchronized method, aby Kod był krótszy i łatwy do zrozumienia

Uwaga

(nie ma to większego znaczenia dla synchronized, jest to różnica między obiektem a klasą lub none-statyczna i statyczna).

  • podczas stosowania synchronized lub normalna metoda lub synchronized(this) lub {[33] } zsynchronizuje bazę na każdej instancji obiektu.
  • gdy użyjesz synchronized lub metody statycznej lub synchronized(class) lub synchronized(static variable) będzie ona zsynchronizowana z klasą

Odniesienie

Https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Hope it help

 12
Author: Phan Van Linh,
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
2018-04-02 01:19:18

Oto Wyjaśnienie z samouczków Javy .

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;
    }
}

Jeśli count jest instancją SynchronizedCounter, to zsynchronizowanie tych metod ma dwa efekty:

  • Po pierwsze, nie jest możliwe przeplatanie dwóch wywołań zsynchronizowanych metod na tym samym obiekcie. Gdy jeden wątek wykonuje zsynchronizowaną metodę dla obiektu, wszystkie inne wątki, które wywołują zsynchronizowane metody dla tego samego bloku obiektu (wstrzymanie wykonania) do czasu zakończenia pierwszego wątku z obiektem.
  • Po drugie, gdy zsynchronizowana metoda kończy działanie, automatycznie ustanawia związek happens-before 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.
 11
Author: Shahryar Saljoughi,
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
2018-12-10 08:30:38

Według mnie synchronized zasadniczo oznacza, że kompilator pisze monitor.wejdź i monitoruj.wyjście wokół metody. Jako taki może być bezpieczny dla wątków w zależności od tego, jak jest używany (chodzi mi o to, że możesz napisać obiekt z zsynchronizowanymi metodami, który nie jest bezpieczny dla wątków w zależności od tego, co robi twoja klasa).

 9
Author: Spence,
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
2009-07-06 07:01:35

To, czego brakuje innym odpowiedzi, to jeden ważny aspekt: bariery pamięci . Synchronizacja wątków składa się zasadniczo z dwóch części: serializacji i widoczności. Odradzam wszystkim googlowanie "bariery pamięci jvm", ponieważ jest to nietrywialny i niezwykle ważny temat (jeśli zmodyfikujesz udostępnione dane dostępne przez wiele wątków). Po zrobieniu tego, radzę spojrzeć na Javę.util.współbieżnych klas pakietu, które pomagają uniknąć korzystania z jawnej synchronizacji, co z kolei pomaga utrzymać proste i wydajne Programy, a może nawet zapobiegać impasom.

Jednym z takich przykładów jest ConcurrentLinkedDeque . Razem z wzorcem poleceń pozwala na tworzenie wysoce wydajnych wątków roboczych poprzez wpychanie poleceń do kolejki współbieżnej - bez wyraźnej synchronizacji, bez możliwych blokad, bez wyraźnej funkcji sleep (), po prostu przepytaj kolejkę przez wywołanie take ().

W skrócie:" synchronizacja pamięci " dzieje się implicite po uruchomieniu wątku wątek się kończy, odczytujesz zmienną zmienną, odblokowujesz monitor (zostawiasz zsynchronizowany blok/funkcję) itp. Ta " synchronizacja "wpływa (w pewnym sensie" spłukuje") wszystkie zapisy wykonane przed tą konkretną czynnością. W przypadku powyższego ConcurrentLinkedDeque dokumentacja "mówi":

Efekty spójności pamięci: podobnie jak w przypadku innych zbiorów współbieżnych, działania w wątku przed umieszczeniem obiektu w ConcurrentLinkedDeque happen-before działania następujące po dostępie lub usunięcie tego elementu z ConcurrentLinkedDeque w innym nić.

To Ukryte zachowanie jest nieco zgubnym aspektem, ponieważ większość programistów Java bez większego doświadczenia weźmie wiele z tego powodu. A potem nagle potykam się o ten wątek po tym jak Java nie robi tego co " ma " robić w produkcji gdzie jest inne obciążenie pracą -- i jest całkiem trudne do przetestowania problemy współbieżności.

 5
Author: user1050755,
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
2017-09-10 23:08:59

Synchronized oznacza po prostu, że wiele wątków, jeśli jest powiązanych z jednym obiektem, może zapobiec brudnemu odczytowi i zapisowi, jeśli zsynchronizowany blok jest używany na danym obiekcie. Aby dać ci więcej jasności, 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 klas MyRunnable : runnable1 jest współdzielony z wątkiem 1, A thread 3 i runnable2 jest współdzielony tylko z wątkiem 2. Teraz, gdy t1 i t3 zaczynają się bez użycia synchronizacji, wyjście PFB sugeruje, że oba wątki 1 i 3 jednocześnie wpływając na wartość var, gdzie Dla wątku 2 var ma własną 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

Używając synchronizacji, wątek 3 czeka na zakończenie wątku 1 we wszystkich scenariuszach. Dostępne są dwa zamki, jeden na runnable1 współdzielony przez wątek 1 i wątek 3 i drugi na runnable2 współdzielony 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
 3
Author: paras4all,
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
2017-06-08 18:41:15

Zsynchronizowane proste oznacza, że żadne dwa wątki nie mogą uzyskać dostępu do bloku/metody jednocześnie. Kiedy mówimy, że dowolny blok / metoda klasy jest zsynchronizowana, oznacza to, że tylko jeden wątek może uzyskać do nich dostęp na raz. Wewnętrznie wątek, który próbuje uzyskać do niego dostęp, najpierw blokuje ten obiekt i tak długo, jak ta blokada nie jest dostępna, żaden inny wątek nie może uzyskać dostępu do żadnej z zsynchronizowanych metod/bloków tej instancji klasy.

Uwaga inny wątek może uzyskać dostęp do metody tego samego obiektu, która jest nie zdefiniowano synchronizacji. Wątek może zwolnić blokadę przez wywołanie

Object.wait()
 1
Author: Aniket Thakur,
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-19 08:11:45

W Javie aby zapobiec manipulowaniu wieloma wątkami przez współdzieloną zmienną używamy słowa kluczowego synchronized. Pozwala to zrozumieć za pomocą następującego przykładu:

W przykładzie zdefiniowałem dwa wątki i nazwałem je increment i decrement. Wątek Increment zwiększa wartość współdzielonej zmiennej (counter) o taką samą wartość wątek decrement zmniejsza ją tzn. 5000 razy jest zwiększana (co daje 5000 + 0 = 5000) i 5000 razy zmniejszamy (co daje 5000-5000 = 0).

Program bez słowa kluczowego synchronized:

class SynchronizationDemo {

    public static void main(String[] args){

        Buffer buffer = new Buffer();                   

        MyThread incThread = new MyThread(buffer, "increment");
        MyThread decThread = new MyThread(buffer, "decrement"); 

        incThread.start();
        decThread.start();  
       
        try {
          incThread.join();
          decThread.join();
        }catch(InterruptedException e){ }

        System.out.println("Final counter: "+buffer.getCounter());
    }
}

class Buffer {
    private int counter = 0; 
    public void inc() { counter++; }
    public void dec() { counter--; } 
    public int getCounter() { return counter; }
}

class MyThread extends Thread {

    private String name;
    private Buffer buffer;

    public MyThread (Buffer aBuffer, String aName) {            
        buffer = aBuffer; 
        name = aName; 
    }

    public void run(){
        for (int i = 0; i <= 5000; i++){
            if (name.equals("increment"))
                buffer.inc();
            else
                buffer.dec();                           
        }
    }
}

Jeśli uruchomimy powyższy program, spodziewamy się, że wartość bufora będzie taka sama, ponieważ zwiększanie i zmniejszanie bufora o tę samą kwotę spowoduje, że wartość początkowa zacznie się od prawa ?. Pozwala zobaczyć wyjście:

Tutaj wpisz opis obrazka

Jak widać bez względu na to, ile razy uruchomimy program, otrzymujemy inny wynik, ponieważ każdy wątek manipulował counter w tym samym czasie. Gdybyśmy mogli pozwolić jeden wątek, który najpierw zwiększy współdzieloną zmienną, a następnie drugi zmniejszy ją lub odwrotnie, otrzymamy odpowiedni wynik, który jest dokładnie tym, co można zrobić za pomocą słowa kluczowego synchronized, dodając słowo kluczowe synchronized przed inc i dec metody Buffer w następujący sposób:

Program ze słowem kluczowym synchronized:

// rest of the code

class Buffer {
    private int counter = 0; 
    // added synchronized keyword to let only one thread
    // be it inc or dec thread to manipulate data at a time
    public synchronized void inc() { counter++; }
    public synchronized void dec() { counter--; } 
    public int getCounter() { return counter; }
}

// rest of the code

I wyjście:

Tutaj wpisz opis obrazka

Bez względu na to, ile razy go uruchomimy, otrzymujemy taki sam wynik jak 0

 0
Author: Ahtisham,
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
2020-09-05 04:12:46

volatile[O firmie] => synchronized

synchronized blok w Javie jest monitorem w wielowątkowości. synchronized blok z tym samym obiektem / klasą może być wykonywany tylko przez pojedynczy wątek, wszystkie inne oczekują. Może pomóc w sytuacji race condition, gdy kilka wątków próbuje zaktualizować tę samą zmienną.

Java 5 Rozszerzony synchronized poprzez wspieranie happens-before[O firmie]

Następuje odblokowanie (zsynchronizowany blok lub wyjście metody) monitora-przed każdym kolejnym blokada (zsynchronizowany blok lub wpis metody) tego samego monitora.

Następny krok to java.util.concurrent

 0
Author: yoAlex5,
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
2020-09-05 17:21:54

Synchronized to słowo kluczowe w języku Java, które służy do tworzenia relacji happens before w środowisku wielowątkowym, aby uniknąć niespójności pamięci i błędu interferencji wątku.

 -6
Author: Sharad,
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
2014-06-19 09:05:26