Synchronizacja w Java

Czym jest Synchronizacja w Java?

In Java, synchronizacja odnosi siฤ™ do moลผliwoล›ci kontrolowania dostฤ™pu wielu wฤ…tkรณw do dowolnego wspรณล‚dzielonego zasobu. Jest to idealne rozwiฤ…zanie, gdy chcemy zezwoliฤ‡ tylko jednemu wฤ…tkowi na dostฤ™p do wspรณล‚dzielonego zasobu.

To podejล›cie do wykonywania jest zwykle okreล›lane jako programowanie `asynchroniczne`. Istniejฤ… rรณwnieลผ wฤ…tki na tych procesorach, ktรณre sฤ… lekkimi procesami, ktรณre mogฤ… wykonywaฤ‡ instrukcje jednoczeล›nie.

Rodzaje Synchronizacja

Istniejฤ… dwa rodzaje metod synchronizacji w Java:

1) Synchronizacja procesรณw

2) Synchronizacja wฤ…tkรณw.

Przestudiujmy wฤ…tek i Synchronizacja procesรณw szczegรณล‚owo.

Synchronizacja procesรณw: Zarzฤ…dza synchronizacjฤ… miฤ™dzy programami. Na przykล‚ad programy takie jak `Microsoft Word` i `Acrobat reader` dziaล‚ajฤ… jako osobne procesy.

Synchronizacja wฤ…tkรณw: Rรณwnoczesne wykonywanie zasobu krytycznego przez dwa lub wiฤ™cej wฤ…tkรณw nazywa siฤ™ wฤ…tkiem Synchronizacja. Moลผna dalej pogrupowaฤ‡ w celu komunikacji wzajemnie wykluczajฤ…cej siฤ™ i miฤ™dzywฤ…tkowej.

Co to jest Zablokuj Java?

Zamknij Java jest zbudowany wokรณล‚ wewnฤ™trznej jednostki zwanej monitorem lub zamkiem. Z kaลผdym obiektem jest powiฤ…zany zamek. Zatem wฤ…tek wymagajฤ…cy staล‚ego dostฤ™pu do pรณl obiektu musi uzyskaฤ‡ blokadฤ™ obiektu przed uzyskaniem do nich dostฤ™pu i zwolniฤ‡ blokadฤ™ po zakoล„czeniu pracy. Dziฤ™ki temu tylko jeden wฤ…tek bฤ™dzie miaล‚ dostฤ™p do udostฤ™pnionych danych w danym momencie.

Program wielowฤ…tkowy z synchronizacjฤ…

Program wielowฤ…tkowy jest metodฤ… lub blokiem zabezpieczonym przed zakล‚รณceniami ze strony innych wฤ…tkรณw wspรณล‚dzielฤ…cych ten sam zasรณb, wskazany za pomocฤ… sล‚owa kluczowego `synchronized`.

Korzystanie z metody synchronizowanej

Kaลผda metoda, ktรณra jest zadeklarowana jako synchronized, jest znana jako synchronized Method. Jest ona rรณwnieลผ uลผywana do blokowania obiektu dla dowolnego wspรณล‚dzielonego zasobu. Tak wiฤ™c, gdy wฤ…tek wywoล‚uje metodฤ™ synchronized, automatycznie przejmuje ona blokadฤ™ dla tego obiektu i zwalnia jฤ…, gdy zakoล„czy swoje zadanie.

Uwaga: Sล‚owo kluczowe synchronized nie moลผe dziaล‚aฤ‡ z klasami i zmiennymi. Tylko metody i bloki mogฤ… byฤ‡ uลผywane ze sล‚owem kluczowym.

Dlaczego warto korzystaฤ‡ z Synchronizowana metoda?

  • Sล‚uลผy do blokowania obiektu dla dowolnych wspรณล‚dzielonych zasobรณw.
  • Obiekt uzyskuje blokadฤ™ za kaลผdym razem, gdy wywoล‚ana zostanie metoda synchronized.
  • Blokada nie zostanie zwolniona, dopรณki gwint nie zakoล„czy swojej funkcji

Skล‚adnia:

Acess_modifiers synchronized return_type method_name (Method_Parameters) {
}
class MathService {
    synchronized void getSumOfArray(int[] numbers) {
     int sum = 0;

         for (int number : numbers) {
             System.out.println(Thread.currentThread()
                     .getName()
                     + " adds "
                     + sum + " to "
                     + number + " to get -> "
                     + (sum += number));

             try {
                 Thread.sleep(500);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
         }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

Wyjaล›nienie Code:

Uruchom ten przykล‚ad i zaobserwuj, ลผe wฤ…tek `0` najpierw pobiera blokadฤ™ obiektu `mathService` i uลผywa tej blokady wyล‚ฤ…cznie do momentu zakoล„czenia wykonywania. W tym kodzie wฤ…tki โ€ž0โ€ i โ€ž1โ€ nie sฤ… przeplatane. Dane wyjล›ciowe sฤ… takie, jak pokazano poniลผej.

Wyjล›cie:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

Korzystanie z bloku synchronizowanego

Zaล‚รณลผmy, ลผe nie chcesz synchronizowaฤ‡ caล‚ej metody. Zamiast tego chcesz zsynchronizowaฤ‡ kilka linii kodu. W tym czasie Syncblok hronic pomรณgล‚ zsynchronizowaฤ‡ wybrane Java kod. SyncDostฤ™p do blokad metod synchronicznych odbywa siฤ™ na poziomie metody, natomiast dostฤ™p do blokad blokรณw synchronicznych odbywa siฤ™ na poziomie obiektu.

class MathService {
    void getSumOfArray(int[] numbers) {
        synchronized (this){
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

Code Wyjaล›nienie:

Po uruchomieniu tego kodu zauwaลผysz, ลผe dziaล‚a on bez ลผadnych zakล‚รณceล„. W metodzie synchronized blokada jest stosowana przez metodฤ™, ale w bloku synchronized blokada jest stosowana przez obiekt. Upewnij siฤ™, ลผe dane wyjล›ciowe sฤ… takie, jak pokazano poniลผej.

Wyjล›cie:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

Wyjaล›nienie kodu:

Gdy uruchomisz ten kod, zauwaลผysz, ลผe dziaล‚a on bez zakล‚รณceล„, czego oczekiwaliล›my. W metodzie synchronized blokada jest stosowana przez metodฤ™, ale w metodzie synchronized block blokada jest stosowana przez obiekt.

Korzystanie ze statycznej synchronizacji

In Java synchronizacja, jeล›li jest wiฤ™cej niลผ jeden obiekt, dwa wฤ…tki mogฤ… nabyฤ‡ blokady i wejล›ฤ‡ do zsynchronizowanego bloku lub bloku, z oddzielnฤ… blokadฤ… dla kaลผdego obiektu. Aby tego uniknฤ…ฤ‡, moลผna uลผyฤ‡ statycznej synchronizacji. Synchronizowane sล‚owa kluczowe bฤ™dฤ… uลผywane przed metodami statycznymi.

Uwaga: W przypadku synchronizacji statycznej dostฤ™p do blokad jest moลผliwy na poziomie klasy, a nie obiektu i metody.

Code aby zademonstrowaฤ‡ problem blokowania wielu obiektรณw

class MathService {
    synchronized void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

Wyjaล›nienie kodu:

Kiedy tworzymy kolejnฤ… instancjฤ™ `MathService`, wprowadzamy interferencjฤ™ w wฤ…tkach, poniewaลผ bฤ™dฤ… one przeplatane z dwoma obiektami. Zauwaลผ, ลผe wฤ…tki `0` i `2` sฤ… przeplatane z tymi dwoma obiektami, podczas gdy wฤ…tki `1` i `3` sฤ… przeplatane z tymi dwoma obiektami.

Wyjล›cie:

Thread-0 adds 0 to 10 to get -> 10
Thread-2 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-2 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-3 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-3 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63
Thread-3 adds 41 to 22 to get -> 63

Ten sam kod wykorzystujฤ…cy metodฤ™ statycznฤ… synchronizowanฤ…

class MathService {
    synchronized static void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

Uruchom powyลผszy kod i zauwaลผ, ลผe wyeliminowaliล›my teraz zakล‚รณcenia wฤ…tkรณw. Wynik kodu pokazano poniลผej.

Wyjล›cie:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-3 adds 0 to 20 to get -> 20
Thread-3 adds 20 to 21 to get -> 41
Thread-3 adds 41 to 22 to get -> 63
Thread-2 adds 0 to 10 to get -> 10
Thread-2 adds 10 to 11 to get -> 21
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

Zalety korzystania z synchronizacji

Oto zalety pracy z wspรณล‚bieลผnymi aplikacjami:

  • Gล‚รณwnym celem synchronizacji w Java ma na celu zapobieganie niespรณjnym danym poprzez zapobieganie interferencji wฤ…tkรณw.
  • Sล‚owo kluczowe synchronized w Java zapewnia blokowanie, ktรณre gwarantuje wzajemnie wyล‚ฤ…czny dostฤ™p do wspรณล‚dzielonego zasobu i zapobiega wyล›cigowi danych.
  • Zapobiega takลผe zmianie kolejnoล›ci instrukcji kodu przez metodฤ™ kompilator, co moลผe powodowaฤ‡ subtelny problem, jeล›li nie uลผyjemy sล‚รณw kluczowych volatile lub synchronized.
  • Synchronized sล‚owo kluczowe odczytuje dane z pamiฤ™ci gล‚รณwnej niลผ z pamiฤ™ci podrฤ™cznej i kiedy zwalnia blokadฤ™.
  • Oprรณลผnia rรณwnieลผ pamiฤ™ฤ‡ gล‚รณwnฤ… z operacji zapisu, eliminujฤ…c bล‚ฤ™dy niespรณjnoล›ci pamiฤ™ci.

Wady SyncMechanizm ronizacji

SyncMechanizmy hronizacji majฤ… sล‚abฤ… wydajnoล›ฤ‡.

Na przykล‚ad

  • Zaล‚รณลผmy, ลผe istnieje piฤ™ฤ‡ procesรณw: A1, A2, A3, A4 i A5.
  • Czekajฤ…, aลผ udostฤ™pnione zasoby bฤ™dฤ… miaล‚y dostฤ™p do jednego wฤ…tku na raz.
  • Wszystkie procesy oczekujฤ…, wiฤ™c ostatni w kolejce musi poczekaฤ‡, aลผ wszystkie inne procesy zostanฤ… zakoล„czone.

Podsumowanie

  • Synchronizacja odnosi siฤ™ do moลผliwoล›ci kontrolowania dostฤ™pu wielu wฤ…tkรณw do dowolnego wspรณล‚dzielonego zasobu.
  • Java ma dwa rodzaje metod synchronizacji: 1) Synchronizacja procesรณw i 2) Synchronizacja wฤ…tkรณw.
  • Zamknij Java jest zbudowany wokรณล‚ wewnฤ™trznej jednostki zwanej monitorem lub zamkiem.
  • Program wielowฤ…tkowy to metoda lub blok zabezpieczony przed zakล‚รณceniami ze strony innych wฤ…tkรณw wspรณล‚dzielฤ…cych ten sam zasรณb, wskazany za pomocฤ… sล‚owa kluczowego `synchronized`.
  • Kaลผda metoda zadeklarowana jako synchronizowana jest nazywana metodฤ… synchronizowanฤ….
  • In JavaDostฤ™p do blokad metod synchronizowanych uzyskuje siฤ™ na poziomie metody, natomiast dostฤ™p do blokad blokรณw synchronizowanych uzyskuje siฤ™ na poziomie obiektu.
  • W przypadku synchronizacji statycznej dostฤ™p do blokad jest moลผliwy na poziomie klasy, a nie obiektu i metody.
  • Gล‚รณwnym celem synchronizacji w Java ma na celu zapobieganie niespรณjnym danym poprzez zapobieganie interferencji wฤ…tkรณw.
  • Najwiฤ™kszฤ… wadฤ… tej metody jest to, ลผe wszystkie procesy czekajฤ…, wiฤ™c ostatni w kolejce musi poczekaฤ‡, aลผ wszystkie inne procesy zostanฤ… zakoล„czone.

Podsumuj ten post nastฤ™pujฤ…co: