Syncsisse hroniseerimine Java

Mis on Syncsisse hroniseerimine Java?

In Java, viitab sรผnkroonimine vรตimalusele kontrollida mitme lรตime juurdepรครคsu mis tahes jagatud ressursile. See on ideaalne vรตimalus, kui tahame lubada ainult รผhe lรตime juurdepรครคsu jagatud ressursile.

Seda tรคitmisviisi nimetatakse tavaliselt "asรผnkroonseks" programmeerimiseks. Nendel protsessoritel on ka lรตime, mis on kerged protsessid, mis suudavad kรคske รผheaegselt tรคita.

Tรผรผbid Synchroniseerimine

Siin on kahte tรผรผpi sรผnkroonimismeetodeid Java:

1) Protsessi sรผnkroonimine

2) Lรตime sรผnkroonimine.

Uurime lรตime ja Protsessi sรผnkroonimine รผksikasjalikult.

Protsessi sรผnkroonimine: See haldab programmide vahelist sรผnkroonimist. Nรคiteks sellised programmid nagu `Microsoft Word` ja `Acrobat reader` tรถรถtavad รผksikute protsessidena.

Lรตime sรผnkroonimine: Kriitilise ressursi samaaegset tรคitmist kahe vรตi enama lรตime poolt nimetatakse lรตimeks Synchroniseerimine. Teid saab rรผhmitada teineteist vรคlistavasse ja lรตimedevahelisse suhtlusse.

Mis on Lock in Java?

Lukusta Java on รผles ehitatud sisemise รผksuse รผmber, mida nimetatakse monitoriks vรตi lukuks. Kรตigil objektidel on nendega seotud lukk. Seega peab lรตim, mis vajab pidevat juurdepรครคsu objekti vรคljadele, omandama objekti lukustuse enne neile juurdepรครคsu saamist ja vabastab lukustuse, kui tรถรถ on tehtud. See tagab, et jagatud andmetele pรครคseb korraga juurde ainult รผks lรตim.

Mitme lรตimega programm koos sรผnkroonimisega

Mitme lรตimega programm on meetod vรตi plokk, mis on kaitstud teiste sama ressurssi jagavate lรตimede hรคirete eest, mis on nรคidatud mรคrksรตnaga "sรผnkroonitud".

Sรผnkroonitud meetodi kasutamine

Kรตiki sรผnkroonituks kuulutatud meetodeid nimetatakse sรผnkroonitud meetoditeks. Seda kasutatakse ka objekti lukustamiseks mis tahes jagatud ressursi jaoks. Niisiis, kui lรตim kutsub esile sรผnkroonitud meetodi. See vรตtab selle objekti luku automaatselt enda valdusesse ja vabastab selle, kui see on oma รผlesande lรตpetanud.

Mรคrge: Sรผnkroonitud mรคrksรตna ei saa tรถรถtada klasside ja muutujatega. Mรคrksรตnaga saab kasutada ainult meetodeid ja plokke.

Miks kasutada Synchroniseeritud meetod?

  • Seda kasutatakse objekti lukustamiseks mis tahes jagatud ressursside jaoks.
  • Objekt lukustub alati, kui kutsutakse sรผnkroonitud meetodit.
  • Lukk ei vabasta enne, kui niit tรคidab oma funktsiooni

sรผntaksit:

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

Selgitus Code:

Kรคivitage see nรคide ja jรคlgige, et lรตim "0" saab esmalt objekti "mathService" luku ja kasutab seda lukku ainult seni, kuni see on tรคitmise lรตpetanud. Lรตime "0" ja "1" ei ole selles koodis vahele jรครคnud. Vรคljund on selline, nagu allpool nรคidatud.

Vรคljund:

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

Sรผnkroniseeritud ploki kasutamine

Oletame, et te ei soovi kogu meetodit sรผnkroonida. Selle asemel soovite sรผnkroonida paar koodirida. Sel ajal, Synchroniseeritud plokk aitas valitud sรผnkroonida Java kood. Synchroniseeritud meetodi lukkudele pรครคseb juurde meetodil, sรผnkroonitud ploki lukkudele aga objektil.

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 Selgitus:

Selle koodi kรคivitamisel mรคrkate, et see tรถรถtab ilma hรคireteta. Sรผnkroniseeritud meetodi puhul rakendab lukku meetod, kuid sรผnkroniseeritud plokis rakendab lukku objekt. Veenduge, et vรคljund oleks nagu allpool nรคidatud.

Vรคljund:

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

Koodi selgitus:

Selle koodi kรคivitamisel mรคrkate, et see tรถรถtab hรคireteta, mida me ootasimegi. Sรผnkroniseeritud meetodi puhul rakendatakse lukku meetodi jรคrgi, sรผnkroniseeritud ploki meetodi puhul aga objekti poolt.

Staatilise sรผnkroonimise kasutamine

In Java sรผnkroonimine, kui objekte on rohkem kui รผks, vรตivad kaks lรตime lukud omandada ja siseneda sรผnkroniseeritud plokki vรตi plokki, kus iga objekti jaoks on eraldi lukk. Selle vรคltimiseks vรตib kasutada staatilist sรผnkroonimist. Synchroniseeritud mรคrksรตnu kasutatakse enne staatilisi meetodeid.

Mรคrge: Staatilises sรผnkroonimises lukustatakse juurdepรครคs klassile, mitte objektile ja meetodile.

Code mitme objekti lukustamise probleemi demonstreerimiseks

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

Koodi selgitus:

Kui loome teenuse โ€žMathServiceโ€ teise eksemplari, tekitame lรตimedes hรคireid, kuna need pรตimitakse kahe objektiga. Pange tรคhele, et lรตime "0" ja lรตime "2" on pรตimitud kahe objektiga, samas kui lรตimed "1" ja "3" on pรตimitud kahe objektiga.

Vรคljund:

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

Sama kood, kasutades sรผnkroniseeritud staatilist meetodit

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

Kรคivitage รผlaltoodud kood ja pange tรคhele, et oleme nรผรผd lรตime hรคired kรตrvaldanud. Koodi vรคljund on nรคidatud allpool.

Vรคljund:

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

Sรผnkroonimise kasutamise eelised

Siin on samaaegsete rakendustega tรถรถtamise eelised:

  • Sรผnkroonimise peamine eesmรคrk Java eesmรคrk on vรคltida vastuolulisi andmeid, vรคltides lรตime hรคireid.
  • Sรผnkroonitud mรคrksรตna sisse Java pakub lukustamist, mis tagab vastastikku vรคlistava juurdepรครคsu jagatud ressursile ja hoiab รคra andmejooksu.
  • Samuti takistab see koodilausete รผmberjรคrjestamist kompilaator, mis vรตib pรตhjustada peent samaaegset probleemi, kui me ei kasuta muutlikke vรตi sรผnkroonitud mรคrksรตnu.
  • Synchroniseeritud mรคrksรตna loeb andmeid pรตhimรคlust kui vahemรคlust ja kui see vabastab luku.
  • Samuti kustutab see pรตhimรคlust kirjutustoimingud, kรตrvaldades mรคlu ebaรผhtluse vead.

Puudused Synchroniseerimismehhanism

Synchroniseerimismehhanismidel on halb jรตudlus.

Nรคiteks

  • Oletame, et protsesse on viis: A1, A2, A3, A4 ja A5.
  • Nad ootavad jagatud ressursside juurdepรครคsu รผhele lรตimele korraga.
  • Kรตik protsessid jรครคvad ootama, nii et jรคrjekorras viimane peab ootama, kuni kรตik muud protsessid on lรตpule viidud.

kokkuvรตte

  • Synchroniseerimine viitab vรตimalusele kontrollida mitme lรตime juurdepรครคsu mis tahes jagatud ressursile.
  • Java on kahte tรผรผpi sรผnkroonimismeetodeid: 1) Protsesside sรผnkroniseerimine ja 2) Lรตime sรผnkroonimine.
  • Lukusta Java on รผles ehitatud sisemise รผksuse รผmber, mida nimetatakse monitoriks vรตi lukuks.
  • Mitme lรตimega programm on meetod vรตi plokk, mis on kaitstud teiste sama ressurssi jagavate lรตimede hรคirete eest, mis on nรคidatud mรคrksรตnaga "sรผnkroonitud".
  • Kรตiki sรผnkroonituks kuulutatud meetodeid nimetatakse sรผnkroonitud meetoditeks.
  • In Java, sรผnkroonitud meetodi lukkudele pรครคseb juurde meetod, samas kui sรผnkroonitud ploki lukkudele pรครคseb juurde objektil.
  • Staatilises sรผnkroonimises lukustatakse juurdepรครคs klassile, mitte objektile ja meetodile.
  • Sรผnkroonimise peamine eesmรคrk Java eesmรคrk on vรคltida vastuolulisi andmeid, vรคltides lรตime hรคireid.
  • Selle meetodi suurim puudus on see, et kรตik protsessid jรครคvad ootele, mistรตttu jรคrjekorras viimane peab ootama, kuni kรตik muud protsessid on lรตpetatud.

Vรตta see postitus kokku jรคrgmiselt: