CodeGym /Java blog /Véletlen /Különbség a Mutex, a monitor és a szemafor között
John Squirrels
Szint
San Francisco

Különbség a Mutex, a monitor és a szemafor között

Megjelent a csoportban
Szia! Amikor többszálas kezelést tanultál a CodeGym-en, gyakran találkoztál a "mutex" és a "monitor" fogalmával. Kukucskálás nélkül meg tudod mondani, miben különböznek egymástól? :) Ha igen, jól sikerült! Ha nem (ez a leggyakoribb), ez nem meglepő. A "Mutex" és a "monitor" valójában rokon fogalmak. Ezen túlmenően, amikor más webhelyeken leckéket olvas és videókat néz a többszálú feldolgozásról, egy másik hasonló fogalommal találkozik: „szemafor”. Nagyon hasonló funkciója van, mint a monitoroknak és a mutexeknek. Ezért fogjuk megvizsgálni ezt a három kifejezést. Megnézünk néhány példát, és végleg megértjük, hogy ezek a fogalmak miben térnek el egymástól :)

Mutex

A mutex (vagy zár) egy speciális mechanizmus a szálak szinkronizálására. Minden Java objektumhoz "csatlakozik" egy – ezt már tudod :) Nem számít, hogy szabványos osztályokat használsz, vagy saját osztályokat hozol létre, pl. Cat and Dog : minden osztály objektumának mutexe van . A "mutex" kifejezés a "MUTual EXclusion" szóból származik, ami tökéletesen leírja a célját. Ahogy az egyik korábbi leckénkben említettük, a mutex lehetővé teszi annak biztosítását, hogy egyszerre csak egy szál férhessen hozzá az objektumhoz. A mutex népszerű valós példája a WC-k. Amikor egy személy belép a WC válaszfalába, belülről bezárja az ajtót. A WC olyan, mint egy tárgy, amelyhez több szálon is hozzá lehet férni. A válaszfalajtó zárja olyan, mint egy mutex, és a kinti emberek sora szálakat képvisel. Az ajtón található zár a WC mutexe: biztosítja, hogy csak egy ember férhessen be. Mi a különbség a mutex, a monitor és a szemafor között?  - 2Más szóval, egyszerre csak egy szál tud működni megosztott erőforrásokkal. Más szálak (emberek) kísérletei a lefoglalt erőforrásokhoz való hozzáférésre kudarcot vallanak. A mutexnek számos fontos tulajdonsága van. Először is csak két állapot lehetséges: "feloldott" és "zárolva". Ez segít megérteni, hogyan működik: párhuzamot vonhat logikai változókkal (igaz/hamis) vagy bináris számokkal (0/1). , az állam nem irányítható közvetlenül. A Java nem rendelkezik olyan mechanizmussal, amely lehetővé tenné egy objektum explicit felvételét, mutex lekérését és a kívánt állapot hozzárendelését. Más szavakkal, nem tehetsz ilyesmit:

Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Ez azt jelenti, hogy nem engedheti fel egy objektum mutexét. Csak a Java gép fér hozzá közvetlenül. A programozók a mutexekkel dolgoznak a nyelv eszközeivel.

Monitor

A monitor egy további "felépítmény" a mutex felett. Valójában a monitor egy kóddarab, amely "láthatatlan" a programozó számára. Amikor korábban a mutexekről beszéltünk, egy egyszerű példát adtunk:

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...some logic, available for all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
A szinkronizált kulcsszóval jelölt kódblokkban megtörténik az obj objektumunk mutexe . Remek, beszerezhetjük a zárat, de pontosan hogyan történik a "védelem"? Amikor a synchronized szót látjuk , mi akadályozza meg, hogy a többi szál belépjen a blokkba? A védelem monitorról származik! A fordító a szinkronizált kulcsszót több speciális kódrészletté alakítja. Még egyszer térjünk vissza a doSomething() metódussal kapcsolatos példánkhoz . Hozzátesszük:

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...some logic, available for all threads

       // Logic available to just one thread at a time
       synchronized (obj) {

           /* Do important work that requires that the object
           be accessed by only one thread */
           obj.someImportantMethod();
       }
   }
}
Íme, mi történik "a motorháztető alatt", miután a fordító átalakítja ezt a kódot:

public class Main {

   private Object obj = new Object();

   public void doSomething() throws InterruptedException {

       // ...some logic, available for all threads

       // Logic available to just one thread at a time:
     
       /* as long as the object's mutex is busy,
       all the other threads (except the one that acquired it) are put to sleep */
       while (obj.getMutex().isBusy()) {
           Thread.sleep(1);
       }

       // Mark the object's mutex as busy
       obj.getMutex().isBusy() = true;

       /* Do important work that requires that the object
       be accessed by only one thread */
       obj.someImportantMethod();

       // Free the object's mutex
       obj.getMutex().isBusy() = false;
   }
}
Persze ez nem igazi példa. Itt Java-szerű kódot használtunk annak ábrázolására, hogy mi történik a Java gépen belül. Ennek ellenére ez a pszeudokód kiváló megértést ad arról, hogy mi történik valójában a szinkronizált blokkon belüli objektummal és szálakkal, és hogyan alakítja a fordító ezt a kulcsszót több olyan utasítássá, amelyek "láthatatlanok" a programozó számára. A Java alapvetően a szinkronizált kulcsszót használja a monitor ábrázolására . Az utolsó példában a szinkronizált kulcsszó helyett megjelenő összes kód a monitor.

Szemafor

Egy másik szó, amellyel találkozni fog a többszálú feldolgozás személyes tanulmányozása során, a „szemafor”. Nézzük meg, mi ez, és miben különbözik a monitortól és a mutextől. A szemafor egy eszköz az erőforrásokhoz való hozzáférés szinkronizálására. Különlegessége, hogy számlálót használ a szinkronizálási mechanizmus létrehozásához. A számláló megmutatja, hogy hány szál férhet hozzá egyszerre a megosztott erőforráshoz. A Java szemaforjait a SemaphoreMi a különbség a mutex, a monitor és a szemafor között?  - 3 osztály képviseli . A szemafor objektumok létrehozásakor a következő konstruktorokat használhatjuk:

Semaphore(int permits)
Semaphore(int permits, boolean fair)
A következőket adjuk át a kivitelezőnek:
    int megengedi — a számláló kezdeti és maximális értéke. Más szóval, ez a paraméter határozza meg, hogy egyidejűleg hány szál férhet hozzá a megosztott erőforráshoz;
  • logikai fair – meghatározza a szálak hozzáférési sorrendjét. Ha a fair igaz, akkor a várakozó szálak abban a sorrendben kapnak hozzáférést, amelyben kérték. Ha hamis, akkor a sorrendet a szálütemező határozza meg.
A szemaforhasználat klasszikus példája az étkezőfilozófus probléma. Mi a különbség a mutex, a monitor és a szemafor között?  - 4A könnyebb érthetőség érdekében egy kicsit leegyszerűsítjük. Képzeld el, hogy van 5 filozófusunk, akinek ebédelnie kell. Ezen kívül van egy asztalunk, amelyen egyszerre legfeljebb két ember fér el. A mi feladatunk az összes filozófus etetése. Egyikük sem éhezhet, és egyikük sem „blokkolhatja” egymást, amikor megpróbál leülni az asztalhoz (el kell kerülnünk a holtpontot). A filozófus óránk így fog kinézni:

class Philosopher extends Thread {

   private Semaphore sem;

   // Did the philosopher eat?
   private boolean full = false;

   private String name;

   Philosopher(Semaphore sem, String name) {
       this.sem=sem;
       this.name=name;
   }

   public void run()
   {
       try
       {
           // If the philosopher has not eaten
           if (!full) {
               // Ask the semaphore for permission to run
               sem.acquire();
               System.out.println(name + " takes a seat at the table");

               // The philosopher eats
               sleep(300);
               full = true;

               System.out.println(name + " has eaten! He leaves the table");
               sem.release();

               // The philosopher leaves, making room for others
               sleep(300);
           }
       }
       catch(InterruptedException e) {
           System.out.println("Something went wrong!");
       }
   }
}
És itt van a kód a programunk futtatásához:

public class Main {

   public static void main(String[] args) {

       Semaphore sem = new Semaphore(2);
       new Philosopher(sem, "Socrates").start();
       new Philosopher(sem,"Plato").start();
       new Philosopher(sem,"Aristotle").start();
       new Philosopher(sem, "Thales").start();
       new Philosopher(sem, "Pythagoras").start();
   }
}
Létrehoztunk egy szemafort, amelynek számlálója 2-re van állítva, hogy teljesüljön a feltétel: egyszerre csak két filozófus tud enni. Vagyis egyszerre csak két szál futhat, mert Filozófus osztályunk örökli a Thread -t ! A Semaphore osztály hanki () és release() metódusai vezérlik a hozzáférési számlálóját. Az hanki() metódus az erőforráshoz való hozzáférést kéri a szemafortól. Ha a számláló >0, akkor a hozzáférés engedélyezve van, és a számláló 1-gyel csökken. A release()metódus "felszabadítja" a korábban megadott hozzáférést, visszaadja a számlálónak (1-gyel növeli a szemafor hozzáférési számlálóját). Mit kapunk a program futtatásakor? Megoldódott a probléma? Nem harcolnak filozófusaink, amíg sorra várnak? :) Íme a konzol kimenete:

Socrates takes a seat at the table 
Plato takes a seat at the table 
Socrates has eaten! He leaves the table 
Plato has eaten! He leaves the table 
Aristotle takes a seat at the table 
Pythagoras takes a seat at the table 
Aristotle has eaten! He leaves the table 
Pythagoras has eaten! He leaves the table 
Thales takes a seat at the table 
Thales has eaten! He leaves the table 
Megcsináltuk! És bár Thalesnek egyedül kellett vacsoráznia, nem hiszem, hogy megbántottuk volna :) Talán észrevett néhány hasonlóságot a mutex és a szemafor között. Valójában ugyanaz a küldetésük: szinkronizálni a hozzáférést bizonyos erőforrásokhoz. Mi a különbség a mutex, a monitor és a szemafor között?  - 5Az egyetlen különbség az, hogy egy objektum mutexét egyszerre csak egy szál szerezheti meg, míg a szálszámlálót használó szemafor esetében egyszerre több szál is hozzáférhet az erőforráshoz. Ez nem csak véletlen :) A mutex valójában egy szemafor1-es számmal. Más szóval, ez egy szemafor, amely egyetlen szálat képes befogadni. „Bináris szemafornak” is nevezik, mivel a számlálója csak 2 értékkel rendelkezhet – 1 ("feloldott") és 0 ("zárolva"). Ez az! Amint látod, mégsem olyan zavaró :) Most, ha szeretnél részletesebben tanulni a többszálú interneten, akkor egy kicsit könnyebb lesz eligazodni ezekben a fogalmakban. Találkozunk a következő leckéken!
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION