Synchronizace v Java

Co je to Synchronizace v Java?

In Java, synchronizace oznaฤuje schopnost ล™รญdit pล™รญstup vรญce vlรกken k libovolnรฉmu sdรญlenรฉmu prostล™edku. Je to ideรกlnรญ moลพnost, kdy chceme povolit pล™รญstup ke sdรญlenรฉmu prostล™edku pouze jednomu vlรกknu.

Tento pล™รญstup k provรกdฤ›nรญ se obvykle nazรฝvรก โ€žasynchronnรญโ€œ programovรกnรญ. Na tฤ›chto procesorech jsou takรฉ vlรกkna, coลพ jsou lehkรฉ procesy, kterรฉ mohou provรกdฤ›t instrukce souฤasnฤ›.

Druhy Synchronizace

Existujรญ dva typy metod synchronizace Java:

1) Synchronizace procesลฏ

2) Synchronizace vlรกken.

Pojฤme studovat vlรกkno a Synchronizace procesลฏ podrobnฤ›.

Synchronizace procesu: Zvlรกdรก synchronizaci mezi programy. Napล™รญklad programy jako `Microsoft Word` a `Acrobat reader` bฤ›ลพรญ jako samostatnรฉ procesy.

Synchronizace vlรกken: Souฤasnรฉ provรกdฤ›nรญ kritickรฉho zdroje dvฤ›ma nebo vรญce vlรกkny se nazรฝvรก vlรกkno Synchronizace. Mลฏลพete bรฝt dรกle seskupeni k vzรกjemnฤ› se vyluฤujรญcรญ komunikaci a komunikaci mezi vlรกkny.

Co je Lock in Java?

Zavล™รญt Java je postaven na vnitล™nรญ entitฤ› znรกmรฉ jako monitor nebo zรกmek. Ke vลกem objektลฏm je pล™idruลพen zรกmek. Takลพe vlรกkno, kterรฉ potล™ebuje konzistentnรญ pล™รญstup k polรญm objektu, musรญ zรญskat zรกmek objektu, neลพ k nim pล™istoupรญ, a uvolnรญ zรกmek, kdyลพ je prรกce hotovรก. Tรญm je zajiลกtฤ›no, ลพe ke sdรญlenรฝm datลฏm pล™istupuje vลพdy pouze jedno vlรกkno.

Vรญcevlรกknovรฝ program se synchronizacรญ

Vรญcevlรกknovรฝ program je metoda nebo blok chrรกnฤ›nรฝ pล™ed ruลกenรญm z jinรฝch vlรกken sdรญlejรญcรญch stejnรฝ zdroj uvedenรฝ pomocรญ klรญฤovรฉho slova `synchronized`.

Pomocรญ synchronizovanรฉ metody

Kaลพdรก metoda, kterรก je deklarovรกna jako synchronizovanรก, je znรกmรก jako synchronizovanรก metoda. Pouลพรญvรก se takรฉ k uzamฤenรญ objektu pro jakรฝkoli sdรญlenรฝ prostล™edek. Takลพe, kdyลพ vlรกkno vyvolรก synchronizovanou metodu. Automaticky pล™evezme zรกmek pro danรฝ objekt a uvolnรญ jej, kdyลพ dokonฤรญ svลฏj รบkol.

Poznรกmka: Synchronizovanรฉ klรญฤovรฉ slovo nemลฏลพe pracovat s tล™รญdami a promฤ›nnรฝmi. S klรญฤovรฝm slovem lze pouลพรญt pouze metody a bloky.

Proฤ pouลพรญvat Syncronizovanรก metoda?

  • Pouลพรญvรก se k uzamฤenรญ objektu pro jakรฉkoli sdรญlenรฉ prostล™edky.
  • Objekt zรญskรก zรกmek pล™i kaลพdรฉm volรกnรญ synchronizovanรฉ metody.
  • Zรกmek se neuvolnรญ, dokud vlรกkno nedokonฤรญ svou funkci

Syntaxe:

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

Vysvฤ›tlenรญ Code:

Spusลฅte tento pล™รญklad a vลกimnฤ›te si, ลพe vlรกkno `0` nejprve zรญskรก zรกmek objektu `mathService` a pouลพรญvรก vรฝhradnฤ› tento zรกmek, dokud nedokonฤรญ provรกdฤ›nรญ. Vlรกkno "0" a "1" nenรญ v tomto kรณdu proloลพeno. Vรฝstup je zobrazen nรญลพe.

Vรฝstup:

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

Pouลพitรญ synchronizovanรฉho bloku

Pล™edpoklรกdejme, ลพe nechcete synchronizovat celou metodu. Mรญsto toho chcete synchronizovat nฤ›kolik ล™รกdkลฏ kรณdu. V tรฉ dobฤ›, Synchronized block pomohl synchronizovat ten vybranรฝ Java kรณd. SyncZรกmky hronized metody jsou pล™รญstupnรฉ na metodฤ›, zatรญmco zรกmky synchronizovanรฝch blokลฏ jsou pล™รญstupnรฉ na objektu.

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 Vysvฤ›tlenรญ:

Po spuลกtฤ›nรญ tohoto kรณdu si vลกimnete, ลพe funguje bez jakรฉhokoli ruลกenรญ. V synchronizovanรฉ metodฤ› je zรกmek aplikovรกn metodou, ale v synchronizovanรฉm bloku je zรกmek aplikovรกn objektem. Ujistฤ›te se, ลพe vรฝstup odpovรญdรก nรกsledujรญcรญmu obrรกzku.

Vรฝstup:

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

Vysvฤ›tlenรญ kรณdu:

Kdyลพ tento kรณd spustรญte, vลกimnete si, ลพe funguje bez ruลกenรญ, coลพ jsme oฤekรกvali. V synchronizovanรฉ metodฤ› je zรกmek aplikovรกn metodou, ale v metodฤ› synchronizovanรฉho bloku je zรกmek aplikovรกn objektem.

Pouลพitรญ statickรฉ synchronizace

In Java synchronizace, pokud existuje vรญce neลพ jeden objekt, dvฤ› vlรกkna mohou zรญskat zรกmky a vstoupit do synchronizovanรฉho bloku nebo bloku se samostatnรฝm zรกmkem pro kaลพdรฝ objekt. Aby se tomu zabrรกnilo, lze pouลพรญt statickou synchronizaci. Syncpล™ed statickรฝmi metodami budou pouลพita klรญฤovรก slova s โ€‹โ€‹hronizovanou hodnotou.

Poznรกmka: Pล™i statickรฉ synchronizaci je pล™รญstup k zรกmku na tล™รญdฤ›, nikoli na objektu a metodฤ›.

Code demonstrovat problรฉm zamykรกnรญ vรญce objektลฏ

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

Vysvฤ›tlenรญ kรณdu:

Kdyลพ vytvoล™รญme dalลกรญ instanci `MathService`, zavedeme interferenci ve vlรกknech, protoลพe budou proloลพena dvฤ›ma objekty. Vลกimnฤ›te si, ลพe vlรกkno `0` a vlรกkno `2` jsou proklรกdรกny tฤ›mito dvฤ›ma objekty, zatรญmco vlรกkna `1` a `3` jsou proklรกdรกny tฤ›mito dvฤ›ma objekty.

Vรฝstup:

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

Stejnรฝ kรณd pomocรญ synchronizovanรฉ statickรฉ metody

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

Spusลฅte vรฝลกe uvedenรฝ kรณd a vลกimnฤ›te si, ลพe jsme nynรญ odstranili interferenci vlรกken. Vรฝstup kรณdu je uveden nรญลพe.

Vรฝstup:

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

Vรฝhody pouลพitรญ synchronizace

Zde jsou vรฝhody pล™i prรกci se soubฤ›ลพnรฝmi aplikacemi:

  • Hlavnรญm cรญlem synchronizace v Java je zabrรกnit nekonzistentnรญm datลฏm tรญm, ลพe zabrรกnรญ interferenci vlรกken.
  • Synchronizovanรฉ klรญฤovรฉ slovo in Java poskytuje zamykรกnรญ, kterรฉ zajiลกลฅuje vzรกjemnฤ› se vyluฤujรญcรญ pล™รญstup ke sdรญlenรฉmu zdroji a zabraลˆuje zรกvodลฏm v datech.
  • Zabraลˆuje takรฉ zmฤ›nฤ› poล™adรญ pล™รญkazลฏ kรณdu pomocรญ kompilรกtor, coลพ mลฏลพe zpลฏsobit jemnรฝ soubฤ›ลพnรฝ problรฉm, pokud nepouลพรญvรกme nestรกlรก nebo synchronizovanรก klรญฤovรก slova.
  • Syncklรญฤovรฉ slovo hronized ฤte data z hlavnรญ pamฤ›ti neลพ z cache a kdyลพ uvolnรญ zรกmek.
  • Takรฉ vyprรกzdnรญ operace zรกpisu z hlavnรญ pamฤ›ti, ฤรญmลพ eliminuje chyby nekonzistence pamฤ›ti.

Nevรฝhody Synchronizaฤnรญ mechanismus

Syncronizaฤnรญ mechanismy majรญ ลกpatnรฝ vรฝkon.

Napล™รญklad

  • Pล™edpoklรกdejme, ลพe existuje pฤ›t procesลฏ, A1, A2, A3, A4 a A5.
  • ฤŒekajรญ, aลพ sdรญlenรฉ prostล™edky pล™istupujรญ k jednomu vlรกknu najednou.
  • Vลกechny procesy ฤekajรญ, takลพe poslednรญ ve frontฤ› musรญ ฤekat, dokud nebudou dokonฤeny vลกechny ostatnรญ procesy.

Shrnutรญ

  • Synchronizace oznaฤuje schopnost ล™รญdit pล™รญstup vรญce vlรกken k libovolnรฉmu sdรญlenรฉmu prostล™edku.
  • Java mรก dva typy metod synchronizace: 1) Synchronizace procesลฏ a 2) Synchronizace vlรกken.
  • Zavล™รญt Java je postaven na vnitล™nรญ entitฤ› znรกmรฉ jako monitor nebo zรกmek.
  • Vรญcevlรกknovรฝ program je metoda nebo blok chrรกnฤ›nรฝ pล™ed ruลกenรญm z jinรฝch vlรกken sdรญlejรญcรญch stejnรฝ zdroj oznaฤenรฝ pomocรญ klรญฤovรฉho slova `synchronized`.
  • Kaลพdรก metoda, kterรก je deklarovรกna jako synchronizovanรก, je znรกmรก jako synchronizovanรก metoda.
  • In Java, synchronizovanรฉ zรกmky metod jsou pล™รญstupnรฉ na metodฤ›, zatรญmco synchronizovanรฉ blokovรฉ zรกmky jsou pล™รญstupnรฉ na objektu.
  • Pล™i statickรฉ synchronizaci je pล™รญstup k zรกmku na tล™รญdฤ›, nikoli na objektu a metodฤ›.
  • Hlavnรญm cรญlem synchronizace v Java je zabrรกnit nekonzistentnรญm datลฏm tรญm, ลพe zabrรกnรญ interferenci vlรกken.
  • Nejvฤ›tลกรญ nevรฝhodou tรฉto metody je, ลพe vลกechny procesy ฤekajรญ, takลพe poslednรญ ve frontฤ› musรญ ฤekat, dokud nebudou dokonฤeny vลกechny ostatnรญ procesy.

Shrลˆte tento pล™รญspฤ›vek takto: