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(); } }
Koodi selgitus:
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(); } }
Koodi 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.
Kood 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.