Páros és páratlan számok nyomtatása 2 szál segítségével

1. Bemutatkozás

Ebben az oktatóanyagban megnézzük, hogyan nyomtathatunk páros és páratlan számokat két szál segítségével.

A cél a számok sorrendben történő nyomtatása, míg az egyik szál csak a páros számokat, a másik szál csak a páratlan számokat nyomtatja ki. A probléma megoldására a szálak szinkronizálásának és a szálak közötti kommunikáció fogalmát fogjuk használni.

2. Szálak Java-ban

A szálak könnyű folyamatok, amelyek egyszerre hajthatók végre. Több szál egyidejű végrehajtása jó lehet a teljesítmény és a CPU kihasználtság szempontjából, mivel egyszerre több feladaton is dolgozhatunk, párhuzamosan futó különböző szálakon keresztül.

További információk a Java szálakról ebben a cikkben találhatók.

A Java-ban szálat hozhatunk létre a cérna osztály vagy a Futható felület. Mindkét esetben felülírjuk a fuss metódust, és írja bele a szál megvalósítását.

További információ arról, hogyan használhatja ezeket a módszereket egy szál létrehozásához, itt található.

3. Szál szinkronizálása

Többszálas környezetben lehetséges, hogy 2 vagy több szál ugyanahhoz az erőforráshoz fér hozzá egy időben. Ez végzetes lehet, és téves eredményekhez vezethet. Ennek megakadályozása érdekében meg kell győződnünk arról, hogy egy adott szálon csak egy szál fér hozzá az erőforráshoz.

Ezt a szál szinkronizálásával érhetjük el.

A Java-ban egy metódust vagy blokkot szinkronizálva jelölhetünk meg, ami azt jelenti, hogy egy adott szálon csak egy szál léphet be a módszerbe vagy blokkba.

A Java szálak szinkronizálásával kapcsolatos további részletek itt találhatók.

4. Szálak közötti kommunikáció

A szálak közötti kommunikáció lehetővé teszi, hogy a szinkronizált szálak metódusok segítségével kommunikáljanak egymással.

Az alkalmazott módszerek a következők várjon, értesíteni, és értesít Mindent, amelyek mind öröklődnek a Tárgy osztály.

Várjon() az aktuális szál korlátlan ideig várakozik, amíg más szál hív Értesítés () vagy Értesítés () ugyanazon a tárgyon. Felhívhatjuk értesít () olyan szálak felébresztésére, amelyek hozzáférést várnak az objektum monitorjához.

Ezen módszerek működéséről további részletek találhatók itt.

5. Páratlan és páros számok nyomtatása alternatívaként

5.1. Használata várjon() és értesít ()

A szinkronizálás és a szálak közötti kommunikáció megvitatott fogalmait használjuk a páratlan és páros számok növekvő sorrendben történő nyomtatásához két különböző szál segítségével.

Az első lépésben megvalósítjuk a Futható interfész mindkét szál logikájának meghatározásához. Ban,-ben fuss módszerrel ellenőrizzük, hogy a szám páros vagy páratlan-e.

Ha a szám páros, akkor a printEven módszere Nyomtató osztály, másképp hívjuk printOdd módszer:

class TaskEvenOdd megvalósítja a Runnable {private int max; magánnyomtató nyomtatás; privát logikai isEvenNumber; // standard konstruktorok @Orride public void run () {int szám = isEvenNumber? 2: 1; while (szám <= max) {if (isEvenNumber) {print.printEven (szám); } else {print.printOdd (szám); } szám + = 2; }}} 

Meghatározzuk a Nyomtató osztály az alábbiak szerint:

osztály Nyomtató {private volatile boolean isOdd; szinkronizált void printEven (int szám) {while (! isOdd) {try {wait (); } catch (InterruptedException e) {Szál.currentThread (). megszakítás (); }} System.out.println (Thread.currentThread (). GetName () + ":" + szám); isOdd = hamis; értesít (); } szinkronizált void printOdd (int szám) {while (isOdd) {próbáld meg {wait (); } catch (InterruptedException e) {Szál.currentThread (). megszakítás (); }} System.out.println (Thread.currentThread (). GetName () + ":" + szám); isOdd = igaz; értesít (); }}

A fő módszerben a megadott osztályt használjuk két szál létrehozásához. Létrehozunk egy objektumot a Nyomtató osztályba, és adja át paraméterként a TaskEvenOdd konstruktőr:

public static void main (String ... args) {Nyomtató nyomtatása = új nyomtató (); Szál t1 = új szál (új TaskEvenOdd (nyomtatás, 10, hamis), "Páratlan"); Szál t2 = új szál (új TaskEvenOdd (nyomtatás, 10, igaz), "Páros"); t1.start (); t2.start (); }

Az első szál a páratlan szál lesz, ezért átmegyünk hamis mint a paraméter értékét isEvenNumber. A második szálhoz átmegyünk igaz helyette. Beállítottuk a maxValue 10-ig mindkét szálnál, így csak az 1-től 10-ig terjedő számokat nyomtatják ki.

Ezután mindkét szálat elindítjuk a Rajt() módszer. Ez a fuss() mindkét szál fentebb meghatározott módszere, ahol ellenőrizzük, hogy a szám páratlan vagy páros-e, és kinyomtatjuk őket.

Amikor a páratlan szál futni kezd, akkor a változó értéke szám lesz 1. Mivel kisebb, mint a maxValue és a zászlót isEvenNumber hamis, printOdd () nak, nek hívják. A módszerben ellenőrizzük, hogy a zászló isOdd igaz és bár igaz, hívunk várjon(). Mivel isOdd kezdetben hamis, várjon() nem kerül meghívásra, és az érték kinyomtatásra kerül.

Ezután beállítottuk a isOdd igazra, így a páratlan szál várakozási állapotba megy és hív értesít () hogy felébressze az egyenletes szálat. A páros szál ekkor felébred, és kinyomtatja a páros számot a páratlan zászló hamis. Ezután felhív értesít () hogy felébressze a páratlan szálat.

Ugyanezt a folyamatot hajtják végre a változó értékéig szám nagyobb, mint a maxValue.

5.2. Szemaforok használata

A szemafor egy számláló segítségével ellenőrzi a megosztott erőforrásokhoz való hozzáférést. Ha a a számláló nagyobb, mint nulla, akkor a hozzáférés megengedett. Ha nulla, akkor a hozzáférést megtagadják.

A Java biztosítja a Szemafor osztály a java.util.egyidejű csomagot, és felhasználhatjuk a megmagyarázott mechanizmus megvalósítására. A szemaforokról további részletek itt találhatók.

Két szálat hozunk létre, egy páratlan szálat és egy páros szálat. A páratlan szál a páratlan számokat 1-től kezdve, a páros szál a páros számokat 2-től kezdődően nyomtatja.

Mindkét szálnak van egy objektuma a SharedPrinter osztály. A SharedPrinter osztálynak két szemaforja lesz, semOdd és semEven amelynek 1 és 0 engedélye lesz a kezdéshez. Ez biztosítja, hogy a páratlan számot nyomtassák ki először.

Két módszerünk van printEvenNum () és printOddNum (). A páratlan szál a printOddNum () metódus és a páros szál a printEvenNum () módszer.

Páratlan szám nyomtatásához a szerez() módszert hívják semOdd, és mivel az eredeti engedély 1, sikeresen megszerzi a hozzáférést, kinyomtatja a páratlan számot és hívásokat kiadás() tovább semEven.

Hívás kiadás() -ig 1-gyel növeli az engedélyt semEven, majd a páros szál sikeresen megszerezheti a hozzáférést és kinyomtathatja a páros számot.

Ez a fent leírt munkafolyamat kódja:

public static void main (String [] args) {SharedPrinter sp = new SharedPrinter (); Thread páratlan = new Thread (új páratlan (sp, 10), "páratlan"); Szál páros = új Szál (új Páros (sp, 10), "Páros"); páratlan.indítás (); még.kezdeni (); }
osztály SharedPrinter {privát szemafor semEven = új szemafor (0); privát szemafor semOdd = új szemafor (1); void printEvenNum (int szám) {try {semEven.acquire (); } catch (InterruptedException e) {Szál.currentThread (). megszakítás (); } System.out.println (Thread.currentThread (). GetName () + szám); semOdd.release (); } void printOddNum (int szám) {try {semOdd.acquire (); } catch (InterruptedException e) {Szál.currentThread (). megszakítás (); } System.out.println (Thread.currentThread (). GetName () + szám); semEven.release (); }} osztály Még a Runnable {private SharedPrinter sp; privát int max; // standard konstruktor @ Override public void run () {for (int i = 2; i <= max; i = i + 2) {sp.printEvenNum (i); }}} páratlan osztály futtatható Runnable {private SharedPrinter sp; privát int max; // standard konstruktorok @Orride public void run () {for (int i = 1; i <= max; i = i + 2) {sp.printOddNum (i); }}}

6. Következtetés

Ebben az oktatóanyagban megvizsgáltuk, hogy miként nyomtathatunk páratlan és páros számokat felváltva a Java két szálának felhasználásával. Két módszert vizsgáltunk ugyanazon eredmények elérése érdekében: felhasználásával várjon() és értesít () és használva Szemafor.

És mint mindig, a teljes munkakód elérhető a GitHubon.