Java-sünkroniseerimine: mida, kuidas ja miks?



See Java sünkroonimist käsitlev artikkel aitab teil juhiseid mitme lõimega programmide sünkroonimise kohta.

Mitme lõimega programmid võivad regulaarselt välja tulla olukorraga, kus mitu katse jõuda samale ressursile, mis annab petturlikke ja hämmastavaid tulemusi. Selle saab lahendada Java-sünkroonimise abil. Ainult üks konkreetne lõim võib ressursile jõuda etteantud ajahetkel. See artikkel aitab teil sünkroonimisstrateegiaga tutvuda.

Ma arutlen teemadel järgmises järjekorras:





Alustame!

Miks kasutada Java-sünkroonimist?



Kui alustate vähemalt kahest lõimest programmi sees, võib olla võimalus, kui mitu lõime üritavad jõuda samasse ressurssi. See võib samaaegsusega seotud probleemide tõttu luua isegi ootamatu tulemuse.

Süntaks :

mis on java keeles awt
sünkroonitud (objektiidentifikaator) {// Juurdepääs jagatud muutujatele ja muudele jagatud ressurssidele}

Näiteks, katse kirjutada samaväärse faili sisse. See võib andmeid rikkuda, kuna üks lõime võib andmed alistada või kui lõim avabsama faili samal ajal, võib mõni teine ​​lõim sama faili sulgeda.On vaja sünkroniseerida mitme lõime tegevus. Seda saab rakendada kontseptsiooni abil M pealtvaatajad .



  • Iga on seotud monitoriga, mille niit saab lukustada või avada.
  • Ainult üks lõng korraga võib monitori lukku hoida.
  • Java programmeerimiskeel pakub väga mugavat viisi lõimede loomiseks ja nende ülesande sünkroonimiseks, kasutades Sünkroonitud plokid.
  • Samuti hoiab jagatud ressursid selles konkreetses plokis.

Java sünkroonitud plokid on tähistatud tähisega Sünkroonitud märksõna. See Java plokk on sünkroonitud mõnel objektil.Kõigil samal objektil sünkroonitud plokkidel saab korraga olla ainult üks lõim. Kõik muud lõimed, mis üritavad sünkroonitud plokki siseneda, on blokeeritud, kuni sünkroonitud ploki sees olev lõime väljub plokist.

Sünkroonimise tüübid

Põhimõtteliselt on saadaval kahte tüüpi sünkroonimist. Nemad on:

  1. Protsessi sünkroonimine: Mitme lõime või protsessi samaaegne käivitamine sellise seisundi saavutamiseks, et nad pühenduksid teatud toimingute jadale.
  2. Lõnga sünkroonimine: Aegadel, kui rohkem kui üks niitproovib juurdepääsu jagatud ressursile, peate tagama, et ressurssi kasutab domeenis ainult üks lõimaeg.

Ärgem laskuge nende tüüpide üksikasjadesse ja proovige mõista, mis on lukud .

Lukud Java-s

Nagu ma varem mainisin, on sünkroonimine ehitatud sisemise üksuse ümber, mida nimetatakse lukk või monitor . Igal objektil on lukk seotud. Niisiis, niit, mis vajab järjepidevat juurdepääsu objekti väljadele, peab enne nende juurde pääsemist omandama objekti lukustuse ja seejärel töö lõpetades luku vabastama.

Java 5-st alates sisaldab pakett java.util.concurrent.locks palju luku rakendusi.

Nii näeb lukk välja:

avaliku klassi lukk {private boolean isLocked = false public sünkroonitud void lock () viskab InterruptedException {while (isLocked) {wait ()} isLocked = true} avalik sünkroonitud void unlock () {isLocked = false false ()}}

Lock () meetod lukustab lukueksemplari nii, et kõik lukku () kutsuvad lõimed on blokeeritud, kuni lukustus () on käivitatud.

Mitme keermestamine ilma sünkroonimiseta

Siin on lihtne näide, mis prindib loenduri väärtuse järjestusse ja iga kord, kui me seda käivitame, annab see lõimile CPU kättesaadavuse põhjal erineva tulemuse. Vaata seda!

klass Multithread {public void printCount () {try {for (int i = 5 i<0 i--) { System.out.println('Counter --- ' + i ) } } catch (Exception e) { System.out.println('Thread interrupted.') } } } class Thread extends Multithread { private Thread t private String threadName Multithread MT Thread( String name, Multithread mt) { threadName = name MT= mt } public void run() { MT.printCount() System.out.println('Thread ' + threadName + ' exiting.') } public void start () { System.out.println('Starting ' + threadName ) if (t == null) { t = new Thread (this, threadName) t.start () } } } public class TestThread { public static void main(String args[]) { Multithread MT = new Multithread() Thread t = new Thread( 'Thread - 1 ', MT) Thread t1 = new Thread( 'Thread - 2 ', MT) t.start() t1.start() // wait for threads to end try { t.join() t1.join() } catch ( Exception e) { System.out.println('Interrupted') } } }

Eespool nimetatud programmi tulemused selles:

Väljund- sünkroonimine Java- Edurekas

Mitme keermega sünkroniseerimine

See on sama näide nagu eespool, kuid see prindib loenduri väärtuse järjestusse. Iga kord, kui seda käivitame, annab see sama tulemuse.

klass Multithread {public void printCount () {proovige {for (int i = 5 i> 0 i--) {System.out.println ('Counter ---' + i)}} catch (Erand e) {System. out.println ('Lõng katkestatud.')}}} klass Lõng laiendab mitmikniiti {private Thread t private String threadName Multithread MT Thread (String name, Multithread mt) {threadName = name MT = mt} public void run () {synchronized ( MT) {MT.printCount ()} System.out.println ('Thread' + threadName + 'exiting.')} Public void start () {System.out.println ('Starting' + threadName) if (t == null) {t = new Thread (this, threadName) t.start ()}}} public class TestThread {public static void main (String args []) {Multithread MT = new Multithread () Thread T = new Thread ('lõim - 1 ', MT) Lõng T1 = uus lõng (' Lõng - 2 ', MT) T.start () T1.start () // oota, kuni lõimed lõpevad, proovige {T.join () T1.join ()} püüd (erand e) {System.out.println ('Katkestatud')}}}

Väljundit on kujutatud allpool:

Sünkroniseeritud märksõna

sünkroonitud märksõna märgib ploki või meetodi kriitilise osa. Kriitiline sektsioon on see, kus korraga töötab ainult üks lõim ja lõim hoiab sünkroonitud sektsiooni lukku. Seda sünkroniseeritud märksõna aitab kirjutada samaaegne mis tahes rakenduse osad. Samuti kaitseb see plokis olevaid jagatud ressursse.

Sünkroonitud märksõna saab kasutada koos:

teisenda string java kuupäevavormingusse

Arutame koodiploki üle.

Sünkroniseeritud märksõna: koodiblokk

Süntaks

Sünkroniseeritud ploki kirjutamise üldine süntaks on järgmine:

sünkroniseeritud (lockObject) {// sünkroonitud avaldused}

Kui lõim soovib plokisisesed sünkroniseeritud laused käivitada, peab ta hankima luku lockObjecti monitoril. Lukustusobjekti monitori saab korraga omandada ainult üks lõim. Seega peavad kõik muud lõimed ootama, kuni parajasti käivitatav lõime lukustuse omandab, ja lõpetama selle täitmise.
Sel moel sünkroniseeritud märksõna tagab, et sünkroonitud plokiväljundeid käivitab korraga ainult üks lõim ja takistab seega mitut lõime plokis sisalduvate jagatud andmete rikkumist.

Märge :

  • Kui magama pannakse niit (kasutades magama () meetod), siis see lukku ei vabasta. Selle uneaja jooksul ei käivita ükski lõime sünkroonitud plokklausendeid.
  • Java sünkroonimine viskab NullPointerException kui lukus objekti kasutatakse sünkroniseeritud (lukk) ‘On null.

Nüüd arutame meetodit.

Sünkroniseeritud märksõna: Meetod

Süntaks

Üldine süntaks kirjutamiseks a sünkroniseeritud meetod on:

sünkroniseeritud meetod (parameetrid) {// sünkroniseeritud kood}

Siin lockObject on lihtsalt viide objektile, mille lukustus on seotud monitoriga, mis tähistab sünkroniseeritud avaldusi.

kuidas javas võimu teha

Sarnaselt sünkroonitud plokiga peab ka lõng sünkroonitud meetodil hankima ühendatud monitori objekti luku. Sünkroniseeritud meetodi korral on lukustusobjekt:

  • ‘.Klass’ objekt - kui antud meetod on staatiline .
  • ‘See’ objekt - kui meetod on mittestaatiline . ‘See’ on viide praegusele objektile, milles sünkroonimeetodit kasutatakse.

Java sünkroonitud märksõna on uuesti siseneja looduses. See tähendab, et kui sünkroniseeritud meetod kutsub mõnda teist sünkroniseeritud meetodit, mis nõuab sama lukustamist, siis saab lukku hoidev praegune niit sellesse meetodisse siseneda ilma lukku omandamata.

Liigume selle artikli viimase teema juurde ja toome välja sünkroonitud märksõna ja sünkroonimisploki suured erinevused.

Erinevus sünkroniseeritud märksõna ja sünkroonitud ploki vahel

  • Kui kasutate sünkroonitud märksõna a-ga meetod , omandab see objekti lukustuse kogu meetodi jaoks. See tähendab, et ükski teine ​​lõim ei saa ühtegi sünkroonimeetodit kasutada enne, kui käimasolev lõim on lõpetatud.
  • Sünkroonitud blokeerida omandab objekti lukustuse ainult sulgude vahel pärast sünkroonitud märksõna täpsustamist. See tähendab, et ükski teine ​​niit ei saa juba lukustatud objektil lukku omandada enne ploki väljumist. Kuid muud lõimed pääsevad juurde ülejäänud koodis, mis on meetodis olemas.

See viib meid selle artikli lõppu, kus oleme arutanud, kuidas Java sünkroonimine täpselt töötab. Loodetavasti on teil selge kõik see, mida teiega selles õpetuses jagati.

Vaadake autor Edureka, usaldusväärne veebiõppeettevõte, mille võrgustik koosneb enam kui 250 000 rahulolevast õppijast ja mis levib üle kogu maailma. Oleme siin, et aidata teil igal sammul teie teekonnal, et saada lisaks sellele Java-intervjuu küsimustele välja, pakume välja õppekava, mis on mõeldud õpilastele ja spetsialistidele, kes soovivad olla Java-arendajad.

Kas teil on meile küsimus? Palun mainige seda selle jaotise „Java sünkroonimine ' artikkel ja me pöördume teie poole niipea kui võimalik.