Udskriv lige og ulige tal ved hjælp af 2 tråde

1. Introduktion

I denne vejledning skal vi se på, hvordan vi kan udskrive lige og ulige tal ved hjælp af to tråde.

Målet er at udskrive tallene i rækkefølge, mens den ene tråd kun udskriver lige tal og den anden tråd kun udskriver de ulige tal. Vi bruger begreberne trådsynkronisering og kommunikation mellem tråde til at løse problemet.

2. Tråde i Java

Tråde er lette processer, der kan udføres samtidigt. Samtidig udførelse af flere tråde kan være god med hensyn til ydeevne og CPU-udnyttelse, da vi kan arbejde på mere end en opgave på én gang gennem forskellige tråde, der kører parallelt.

Flere oplysninger om tråde i Java kan findes i denne artikel.

I Java kan vi oprette en tråd ved enten at udvide Tråd klasse eller ved at implementere Kan køres interface. I begge tilfælde tilsidesætter vi løb metode og skriv implementeringen af ​​tråden i den.

Flere oplysninger om, hvordan du bruger disse metoder til at oprette en tråd, kan findes her.

3. Trådsynkronisering

I et miljø med flere tråde er det muligt, at 2 eller flere tråde har adgang til den samme ressource omkring samme tid. Dette kan være fatalt og føre til fejlagtige resultater. For at forhindre dette skal vi sørge for, at kun en tråd får adgang til ressourcen på et givet tidspunkt.

Vi kan opnå dette ved hjælp af trådsynkronisering.

I Java kan vi markere en metode eller blokering som synkroniseret, hvilket betyder, at kun en tråd vil være i stand til at indtaste denne metode eller blokere på et givet tidspunkt.

Flere detaljer om trådsynkronisering i Java kan findes her.

4. Inter-trådkommunikation

Inter-thread kommunikation tillader synkroniserede tråde at kommunikere med hinanden ved hjælp af et sæt metoder.

De anvendte metoder er vente, underrette, og underret alle, som alle er arvet fra Objekt klasse.

Vente() får den aktuelle tråd til at vente på ubestemt tid, indtil nogle andre tråde kalder notify () or notifyAll () på det samme objekt. Vi kan ringe underrette() at vække tråde, der venter på adgang til dette objekts skærm.

Flere detaljer om brugen af ​​disse metoder kan findes her.

5. Alternativt udskrivning af ulige og lige tal

5.1. Ved brug af vente() og underrette()

Vi bruger de diskuterede begreber synkronisering og kommunikation mellem tråde til at udskrive ulige og lige tal i stigende rækkefølge ved hjælp af to forskellige tråde.

I det første trin implementerer vi Kan køres interface til at definere logikken for begge tråde. I løb metode, kontrollerer vi, om antallet er lige eller ulige.

Hvis antallet er lige, kalder vi printEven metode til Printer klasse, ellers kalder vi printOdd metode:

klasse TaskEvenOdd implementerer Runnable {private int max; privat printer udskrivning; privat boolsk isEvenNumber; // standardkonstruktører @ Override public void run () {int number = isEvenNumber? 2: 1; mens (nummer <= maks) {hvis (isEvenNumber) {print.printEven (nummer); } andet {print.printOdd (nummer); } nummer + = 2; }}} 

Vi definerer Printer klasse som følger:

klasse printer {privat flygtig boolsk isOdd; synkroniseret ugyldig printEven (int-nummer) {mens (! isOdd) {prøv {vent (); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); }} System.out.println (Thread.currentThread (). GetName () + ":" + nummer); isOdd = falsk; underrette(); } synkroniseret ugyldig printOdd (int-nummer) {mens (isOdd) {prøv {vent (); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); }} System.out.println (Thread.currentThread (). GetName () + ":" + nummer); isOdd = sandt; underrette(); }}

I hovedmetoden bruger vi den definerede klasse til at oprette to tråde. Vi skaber et objekt af Printer klasse og videregive den som parameter til TaskEvenOdd konstruktør:

public static void main (String ... args) {Printer print = new Printer (); Tråd t1 = ny tråd (ny TaskEvenOdd (print, 10, falsk), "Ulig"); Tråd t2 = ny tråd (ny TaskEvenOdd (print, 10, sand), "Jævn"); t1.start (); t2.start (); }

Den første tråd vil være den ulige tråd, derfor passerer vi falsk som parameterens værdi isEvenNumber. For den anden tråd passerer vi rigtigt i stedet. Vi indstiller maxValue til 10 for begge tråde, så kun tallene fra 1 til 10 udskrives.

Vi starter derefter begge tråde ved at kalde Start() metode. Dette vil påberåbe sig løb() metode til begge tråde som defineret ovenfor, hvor vi kontrollerer, om antallet er ulige eller lige og udskriver dem.

Når den ulige tråd begynder at køre, er værdien af ​​variablen nummer bliver 1. Da det er mindre end maxValue og flaget isEvenNumber er falsk, printOdd () Hedder. I metoden kontrollerer vi, om flaget erOdd er sandt, og mens det er sandt, kalder vi vente(). Siden erOdd er falsk oprindeligt, vente() kaldes ikke, og værdien udskrives.

Vi indstiller derefter værdien af erOdd til sandt, så den ulige tråd går i ventetilstand og kalder underrette() at vække den lige tråd. Den lige tråd vågner derefter op og udskriver det lige antal siden ulige flag er falsk. Derefter kalder det underrette() at vække den ulige tråd.

Den samme proces udføres indtil værdien af ​​variablen nummer er større end maxValue.

5.2. Brug af semaforer

En semafor styrer adgangen til en delt ressource ved hjælp af en tæller. Hvis den tælleren er større end nul, så er adgang tilladt. Hvis det er nul, nægtes adgang.

Java leverer Semafor klasse i java.util.concurrent pakke, og vi kan bruge den til at implementere den forklarede mekanisme. Flere detaljer om semaforer kan findes her.

Vi opretter to tråde, en ulige tråd og en jævn tråd. Den ulige tråd udskriver de ulige numre, der starter fra 1, og den lige tråd udskriver lige numre, der starter fra 2.

Begge tråde har et objekt af Delt printer klasse. Det Delt printer klassen vil have to semaforer, semOdd og semEven som vil have 1 og 0 tilladelser til at begynde med. Dette vil sikre, at ulige antal først udskrives.

Vi har to metoder printEvenNum () og printOddNum (). Den ulige tråd kalder printOddNum () metode og den lige tråd kalder printEvenNum () metode.

Hvis du vil udskrive et ulige tal, skal erhverve() metode kaldes semOdd, og da den oprindelige tilladelse er 1, får den adgangen med succes, udskriver det ulige nummer og kalder op frigøre()semEven.

Ringer frigøre() vil forøge tilladelsen med 1 for semEven, og den lige tråd kan derefter med succes få adgang og udskrive lige nummer.

Dette er koden til den ovenfor beskrevne arbejdsgang:

public static void main (String [] args) {SharedPrinter sp = new SharedPrinter (); Tråd ulige = ny tråd (ny ulige (sp, 10), "ulige"); Tråd lige = ny tråd (ny jævn (sp, 10), "jævn"); odd.start (); even.start (); }
klasse SharedPrinter {privat Semaphore semEven = ny Semaphore (0); privat Semaphore semOdd = ny Semaphore (1); ugyldig printEvenNum (int num) {prøv {semEven.acquire (); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); } System.out.println (Thread.currentThread (). GetName () + num); semOdd.release (); } ugyldigt printOddNum (int num) {prøv {semOdd.acquire (); } fange (InterruptedException e) {Thread.currentThread (). interrupt (); } System.out.println (Thread.currentThread (). GetName () + num); semEven.release (); }} klasse Selv implementerer Runnable {private SharedPrinter sp; privat int max; // standardkonstruktør @ Override public void run () {for (int i = 2; i <= max; i = i + 2) {sp.printEvenNum (i); }}} klasse Odd implementerer Runnable {private SharedPrinter sp; privat int max; // standardkonstruktører @ Override public void run () {for (int i = 1; i <= max; i = i + 2) {sp.printOddNum (i); }}}

6. Konklusion

I denne vejledning har vi kigget på, hvordan vi kan udskrive ulige og lige tal alternativt ved hjælp af to tråde i Java. Vi kiggede på to metoder til at opnå de samme resultater: ved brug af vente() og underrette() og ved hjælp af en Semafor.

Og som altid er den fulde arbejdskode tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found