Synchronisatie in Java: wat, hoe en waarom?



Dit artikel over synchronisatie in Java helpt u bij het synchroniseren van multi-threaded programma's.

Programma's met meerdere threads kunnen regelmatig een omstandigheid tegenkomen waarbij meerdere proberen om bij dezelfde bron te komen die frauduleuze en verrassende resultaten oplevert. Dit kan worden opgelost door gebruik te maken van de synchronisatie in Java. Slechts één specifieke thread kan de bron op een bepaald tijdstip bereiken. Dit artikel helpt u vertrouwd te raken met de synchronisatiestrategie.

Ik bespreek de onderwerpen in deze volgorde:





Laten we beginnen!

Waarom synchronisatie in Java gebruiken?



Als u begint met ten minste twee threads in een programma, bestaat de kans dat meerdere threads proberen dezelfde bron te bereiken. Het kan zelfs een onverwacht resultaat opleveren vanwege problemen met gelijktijdigheid.

Syntaxis :

gesynchroniseerd (objectidentifier) ​​{// Toegang tot gedeelde variabelen en andere gedeelde bronnen}

Bijvoorbeeld, probeer te schrijven in een gelijkwaardig bestand. Dit kan de gegevens beschadigen, aangezien een van de threads de gegevens kan overschrijven of wanneer een thread hethetzelfde bestand tegelijkertijd, kan een andere thread hetzelfde bestand sluiten.Het is nodig om de actie van meerdere threads te synchroniseren. Dit kan worden geïmplementeerd met behulp van een concept genaamd M. onitors .



  • Elk wordt geassocieerd met een monitor, die een thread kan vergrendelen of ontgrendelen.
  • Slechts één draad tegelijk kan een slot op een monitor vasthouden.
  • Java programmeertaal biedt een zeer handige manier om threads te maken en hun taak te synchroniseren door de Gesynchroniseerd blokken.
  • Het houdt ook de gedeelde bronnen binnen dit specifieke blok.

Gesynchroniseerde blokken in Java zijn gemarkeerd met de Gesynchroniseerd trefwoord. Dit blok in Java is gesynchroniseerd op een object.Alle blokken die op hetzelfde object worden gesynchroniseerd, kunnen slechts één thread tegelijk bevatten. Alle andere threads die proberen het gesynchroniseerde blok binnen te gaan, worden geblokkeerd totdat de thread in het gesynchroniseerde blok het blok verlaat.

Soorten synchronisatie

Er zijn in principe twee soorten synchronisatie beschikbaar. Zij zijn:

  1. Processynchronisatie: De gelijktijdige uitvoering van meerdere threads of processen om een ​​toestand te bereiken waarin ze zich verbinden tot een bepaalde reeks acties.
  2. Draadsynchronisatie: Soms wanneer meer dan één threadprobeert toegang te krijgen tot een gedeelde bron, moet u ervoor zorgen dat die bron slechts door één thread wordt gebruikt opeen tijd.

Laten we niet ingaan op de details van deze typen en proberen te begrijpen wat vergrendelingen zijn .

Vergrendelt in Java

Zoals ik eerder al zei, is synchronisatie gebouwd rond een interne entiteit die bekend staat als de slot of toezicht houden op . Elk object heeft een bijbehorend slot. Dus een thread die consistente toegang tot de velden van een object nodig heeft, moet de vergrendeling van het object verkrijgen voordat hij er toegang toe krijgt, en vervolgens de vergrendeling loslaten wanneer het werk is voltooid.

Vanaf Java 5 bevat het pakket java.util.concurrent.locks veel lock-implementaties.

een reeks objecten maken

Dit is hoe een slot eruit ziet:

public class Lock {private boolean isLocked = false public gesynchroniseerd ongeldig slot () gooit InterruptedException {while (isLocked) {wait ()} isLocked = true} publiek gesynchroniseerd ongeldig unlock () {isLocked = false informeren ()}}

De methode lock () vergrendelt de Lock-instantie zodat alle threads die lock () aanroepen worden geblokkeerd totdat unlock () wordt uitgevoerd.

Multi-threading zonder synchronisatie

Hier is een eenvoudig voorbeeld dat de tellerwaarde in een reeks afdrukt en elke keer dat we het uitvoeren, produceert het een ander resultaat op basis van CPU-beschikbaarheid voor een thread. Kijk hier eens naar!

class Multithread {public void printCount () {probeer {voor (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') } } }

Het bovenstaande programma resulteert hierin:

Uitgangssynchronisatie in Java Edureka

overschrijven en overbelasting in java

Multi-threading met synchronisatie

Dit is hetzelfde voorbeeld als hierboven, maar het drukt de tellerwaarde in de reeks af. Elke keer dat we het uitvoeren, levert het hetzelfde resultaat op.

class Multithread {public void printCount () {probeer {voor (int i = 5 i> 0 i--) {System.out.println ('Counter ---' + i)}} catch (uitzondering e) {System. out.println ('Thread onderbroken.')}}} class Thread breidt uit Multithread {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 = nieuwe 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 = nieuwe Thread (' Thread - 2 ', MT) T.start () T1.start () // wacht tot de threads zijn beëindigd probeer {T.join () T1.join ()} catch (uitzondering e) {System.out.println ('Interrupted')}}}

De output wordt hieronder weergegeven:

Gesynchroniseerd trefwoord

gesynchroniseerd trefwoord markeert een blok of een methode als een kritische sectie. Een kritieke sectie is waar slechts één thread tegelijk wordt uitgevoerd, en de thread bevat de vergrendeling voor de gesynchroniseerde sectie. Deze gesynchroniseerd trefwoord helpt bij het schrijven gelijktijdig delen van elke toepassing. Het beschermt ook gedeelde bronnen binnen het blok.

Het gesynchroniseerde trefwoord kan worden gebruikt met:

Laten we het codeblok bespreken.

Gesynchroniseerd trefwoord: een codeblok

Syntaxis

De algemene syntaxis voor het schrijven van een gesynchroniseerd blok is:

gesynchroniseerd (lockObject) {// gesynchroniseerde instructies}

Wanneer een thread de gesynchroniseerde instructies in het blok wil uitvoeren, moet deze de vergrendeling op de monitor van lockObject verwerven. Slechts één thread kan tegelijkertijd de monitor van een slotobject verkrijgen. Dus alle andere threads moeten wachten tot de momenteel uitgevoerde thread de vergrendeling verwerft en de uitvoering ervan heeft voltooid.
Op deze manier kan de gesynchroniseerd trefwoord garandeert dat slechts één thread de gesynchroniseerde blokinstructies tegelijk uitvoert, en voorkomt zo dat meerdere threads de gedeelde gegevens die in het blok aanwezig zijn, beschadigen.

Opmerking :

  • Als er een draad op slaap wordt gezet (met slaap() methode), dan wordt het slot niet vrijgegeven. Tijdens deze slaaptijd zal geen enkele thread de gesynchroniseerde blokinstructies uitvoeren.
  • Java-synchronisatie zal gooien NullPointerException als vergrendelingsobject gebruikt in ‘ gesynchroniseerd (vergrendelen) ' is niets.

Laten we nu de methode bespreken.

Gesynchroniseerd trefwoord: Een methode

Syntaxis

De algemene syntaxis voor het schrijven van een gesynchroniseerde methode is:

gesynchroniseerde methode (parameters) {// gesynchroniseerde code}

Hier lockObject is slechts een verwijzing naar een object waarvan het slot is gekoppeld aan de monitor die de gesynchroniseerde instructies vertegenwoordigt.

wat is een pojo-gebaseerd programmeermodel

Net als bij het gesynchroniseerde blok, moet een thread de vergrendeling op het aangesloten monitorobject verkrijgen met de gesynchroniseerde methode. In het geval van een gesynchroniseerde methode is het vergrendelingsobject:

  • ‘.Class’ -object - als de gegeven methode is statisch .
  • ‘Dit’ object - als de methode is niet statisch . ‘This’ is de verwijzing naar het huidige object waarin de gesynchroniseerde methode wordt aangeroepen.

Het Java-gesynchroniseerde trefwoord is herintreder in de natuur. Het betekent dat als een gesynchroniseerde methode een andere gesynchroniseerde methode aanroept die dezelfde vergrendeling vereist, de huidige thread die de vergrendeling vasthoudt, die methode kan gebruiken zonder de vergrendeling te verwerven.

Laten we verder gaan met het laatste onderwerp van dit artikel en wijzen op de belangrijkste verschillen tussen het gesynchroniseerde trefwoord en het synchronisatieblok.

Verschil tussen gesynchroniseerd trefwoord en gesynchroniseerd blok

  • Als u een gesynchroniseerd trefwoord gebruikt met een methode , verwerft het een slot in het object voor de hele methode. Dit betekent dat geen enkele andere thread een gesynchroniseerde methode kan gebruiken totdat de huidige thread die wordt aangeroepen, zijn uitvoering heeft voltooid.
  • Gesynchroniseerd blok verwerft alleen een vergrendeling in het object tussen haakjes nadat het gesynchroniseerde sleutelwoord is opgegeven. Dit betekent dat geen enkele andere thread een vergrendeling op het reeds vergrendelde object kan krijgen totdat het blok wordt afgesloten. Maar andere threads hebben toegang tot de rest van de code die in de methode aanwezig is.

Dit brengt ons bij het einde van dit artikel waar we hebben besproken hoe synchronisatie in Java precies werkt. Ik hoop dat je duidelijk bent met alles wat in deze tutorial met je is gedeeld.

Bekijk de door Edureka, een vertrouwd online leerbedrijf met een netwerk van meer dan 250.000 tevreden leerlingen verspreid over de hele wereld. We zijn hier om je te helpen bij elke stap op je reis, om naast deze Java-interviewvragen ook een curriculum te bedenken dat is ontworpen voor studenten en professionals die een Java-ontwikkelaar willen worden.

Heeft u een vraag voor ons? Vermeld het in het commentaargedeelte van deze “Synchronisatie in Java ' artikel en we nemen zo snel mogelijk contact met u op.