JavaRush /Java Blogu /Random-AZ /Muteks, monitor və semafor arasındakı fərq nədir

Muteks, monitor və semafor arasındakı fərq nədir

Qrupda dərc edilmişdir
Salam! JavaRush-da multithreading öyrənərkən tez-tez “mutex” və “monitor” anlayışlarına rast gəlirdiniz. İndi baxmadan onların necə fərqləndiyini cavablandıra bilərsinizmi? :) Muteks, monitor və semafor arasındakı fərq nədir - 1Mümkünsə, afərin! Əgər yoxsa (və çox vaxt bu baş verir) - təəccüblü deyil. "Muteks" və "monitor" anlayışları həqiqətən də əlaqəlidir. Üstəlik, mühazirələri oxuyarkən və İnternetdə xarici mənbələrdə çoxillikli videolara baxarkən başqa bir oxşar anlayışla - "semafora" rastlaşacaqsınız. Onun funksionallığı da əsasən monitora və mutexə bənzəyir. Odur ki, gəlin bu üç termini anlayaq, bir neçə misala baxaq və nəhayət, onların bir-birindən nə ilə fərqləndiyini anlayaq :)

Muteks

Muteks mövzuları sinxronlaşdırmaq üçün xüsusi bir obyektdir. O, Java-da hər bir obyektə “əlavədir” – siz artıq bilirsiniz ki, standart siniflərdən istifadə etməyiniz və ya öz siniflərinizi yaratmağınızın fərqi yoxdur, deyək ki Cat, Dogbütün siniflərin bütün obyektlərində mutex var . "Muteks" adı ingiliscə "MUTual Exclusion" - "qarşılıqlı istisna" sözündən gəlir və bu, onun məqsədini mükəmməl şəkildə əks etdirir. Əvvəlki mühazirələrdən birində dediyimiz kimi, mutexin vəzifəsi belə bir mexanizm təmin etməkdir ki, müəyyən bir zamanda obyektə yalnız bir iplik daxil ola bilər . Muteks üçün məşhur real həyat bənzətməsi “tualet nümunəsidir”. İnsan tualetə girəndə qapını içəridən bağlayır. Tualet bir neçə iplə əldə edilə bilən bir obyekt kimi çıxış edir. Tualetin qapısındakı qıfıl mutex rolunu, çöldəki insanların növbəsi isə sapların rolunu oynayır. Qapıdakı kilid tualet mutexidir: o, eyni anda yalnız bir nəfərin içəridə olmasını təmin edir. Muteks, monitor və semafor arasındakı fərq nədir - 2Başqa sözlə, paylaşılan resurslar üzərində eyni anda yalnız bir mövzu işləyə bilər. Digər mövzuların (insanların) işğal edilmiş resurslara daxil olmaq cəhdləri uğursuz olacaq. Muteks bir neçə vacib xüsusiyyətə malikdir. Birincisi , yalnız iki vəziyyət mümkündür - "azad" və "məşğul". Bu, onun necə işlədiyini başa düşməyi asanlaşdırır: doğru/yanlış Boole dəyişənləri və ya ikili say sistemi 1/0 ilə paralellər çəkilə bilər. İkincisi , dövlətlərə birbaşa nəzarət etmək olmaz. Java-da obyekti açıq şəkildə götürməyə, onun mutexini əldə etməyə və ona istədiyiniz statusu təyin etməyə imkan verən mexanizmlər yoxdur. Başqa sözlə, belə bir şey edə bilməzsiniz:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Beləliklə, obyektin mutexi buraxıla bilməz. Yalnız Java maşınının ona birbaşa çıxışı var. Proqramçılar dil alətlərindən istifadə edərək mutekslərlə işləyirlər.

Ekran

Monitor mutex üçün əlavə “əlavədir”. Əslində, monitor proqramçı üçün “görünməz” kod parçasıdır . Əvvəllər mutex haqqında danışarkən sadə bir misal verdik:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       //...some logic available to all threads

       synchronized (obj) {

           //logic that is only available to one thread at a time
       }
   }
}
Sözlə işarələnmiş kod blokunda synchronizedobyektimizin mutexi tutulur obj. Yaxşı, tutulma baş verir, amma "müdafiə mexanizmi" necə əldə edilir? Niyə başqa mövzular bir söz görəndə synchronizedblokun içərisinə girə bilmir ? Qoruyucu mexanizmi yaradan monitordur! Kompilyator sözü synchronizedbir neçə xüsusi kod parçasına çevirir. Bir daha metodla nümunəmizə qayıdaq doSomething()və ona əlavə edək:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       //...some logic available to all threads

       //logic that is only available to one thread at a time
       synchronized (obj) {

           /*выполнить важную работу, при которой доступ к an objectу
           должен быть только у одного потока*/
           obj.someImportantMethod();
       }
   }
}
Kompilyator bu kodu çevirdikdən sonra proqramımızın "başlıq altında" nə baş verəcək:
public class Main {

   private Object obj = new Object();

   public void doSomething() throws InterruptedException {

       //...some logic available to all threads

       //логика, которая одновременно доступна только для одного потока:

       /*до тех пор, пока мьютекс an object занят -
       любой другой поток (кроме того, который его захватил), спит*/
       while (obj.getMutex().isBusy()) {
           Thread.sleep(1);
       }

       //пометить мьютекс an object How занятый
       obj.getMutex().isBusy() = true;

       /*выполнить важную работу, при которой доступ к an objectу
       должен быть только у одного потока*/
       obj.someImportantMethod();

       //освободить мьютекс an object
       obj.getMutex().isBusy() = false;
   }
}
Məsələn, təbii ki, real deyil. Burada Java-ya bənzər koddan istifadə edərək, Java maşınının içərisində bu anda baş verənləri əks etdirməyə çalışdıq. Bununla belə, bu psevdokod blok daxilində obyekt və mövzularla əslində nə baş verdiyini synchronizedvə tərtibçinin bu sözü proqramçı üçün “görünməz” olan bir neçə əmrə necə çevirdiyini yaxşı başa düşür. Əslində, Java-da monitor sözü ilə ifadə edilirsynchronized . Son misalda sözün yerinə görünən bütün kodlar synchronizedmonitordur.

Semafor

Multithreading-i təkbaşına öyrənərkən rastlaşdığınız başqa bir söz “semafor”dur. Bunun nə olduğunu və monitor və mutexdən nə ilə fərqləndiyini anlayaq. Semafor resursa girişi sinxronlaşdırmaq üçün bir vasitədir. Onun özəlliyi ondadır ki, sinxronizasiya mexanizmi yaratarkən sayğacdan istifadə edir. Sayğac bizə neçə mövzunun eyni vaxtda paylaşılan mənbəyə daxil ola biləcəyini bildirir. Muteks, monitor və semafor arasında fərq nədir - 3Java-da semaforlar siniflə təmsil olunur Semaphore. Semafor obyektləri yaradarkən aşağıdakı konstruktorlardan istifadə edə bilərik:
Semaphore(int permits)
Semaphore(int permits, boolean fair)
Konstruktora keçirik:
  • int permits— ilkin və maksimum sayğac dəyəri. Yəni, paylaşılan mənbəyə eyni anda neçə mövzu daxil ola bilər;

  • boolean fair- mövzuların giriş əldə etmə sırasını təyin etmək. Əgər fair= true olarsa , giriş gözləyən mövzulara tələb etdikləri ardıcıllıqla verilir. Yanlışdırsa , sifariş mövzu planlayıcısı tərəfindən müəyyən ediləcək .

Semaforlardan istifadənin klassik nümunəsi filosofların nahar problemidir .
Muteks, monitor və semafor arasındakı fərq nədir - 4
Daha yaxşı başa düşmək üçün onun şərtlərini bir az sadələşdirəcəyik. Təsəvvür edin ki, nahara ehtiyacı olan 5 filosofumuz var. Eyni zamanda, bir masamız var və eyni vaxtda iki nəfərdən çox adam ola bilməz. Bizim vəzifəmiz bütün filosofları qidalandırmaqdır. Onların heç biri ac qalmamalı, masa arxasında oturmaq istəyərkən bir-birini “manələməməli” (biz dalana dirənməməliyik). Filosof sinifimiz belə görünəcək:
class Philosopher extends Thread {

   private Semaphore sem;

   // поел ли философ
   private boolean full = false;

   private String name;

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

   public void run()
   {
       try
       {
           // если философ еще не ел
           if (!full) {
               //Запрашиваем у семафора разрешение на выполнение
               sem.acquire();
               System.out.println (name + " садится за стол");

               // философ ест
               sleep(300);
               full = true;

               System.out.println (name + " поел! Он выходит из-за стола");
               sem.release();

               // философ ушел, освободив место другим
               sleep(300);
           }
       }
       catch(InterruptedException e) {
           System.out.println ("What-то пошло не так!");
       }
   }
}
Proqramımızı işlətmək üçün kod budur:
public class Main {

   public static void main(String[] args) {

       Semaphore sem = new Semaphore(2);
       new Philosopher(sem,"Сократ").start();
       new Philosopher(sem,"Платон").start();
       new Philosopher(sem,"Аристотель").start();
       new Philosopher(sem,"Фалес").start();
       new Philosopher(sem,"Пифагор").start();
   }
}
Yalnız iki filosofun eyni vaxtda yeyə bilməsi şərtini təmin etmək üçün 2 sayı ilə semafor yaratdıq. Yəni, yalnız iki ip eyni vaxtda işləyə bilər, çünki bizim sinfimiz Philosopher-dən miras qalıb Thread! Sinif acquire()və metodlar onun icazə sayğacını idarə edir. Metod semafordan resursa daxil olmaq üçün icazə tələb edir. Əgər sayğac > 0 olarsa, icazə verilir və sayğac 1 azalır. Metod əvvəllər verilmiş icazəni “buraxır” və onu sayğaca qaytarır (semaforun qrant sayğacını 1 artıraraq). Proqramı işlədəndə nə əldə edirik? Problem həll olundumu, filosoflarımız öz növbəsini gözləyərək mübarizə aparacaqlarmı? :) Aldığımız konsol çıxışı budur: Sokrat masaya oturur Platon Sokratın yediyi masaya oturur! Süfrəni tərk etdi, Platon yedi! O stolu tərk edir Aristotel masaya oturur Pifaqor Aristotelin yediyi masaya oturur! Pifaqorun yediyi süfrəni tərk edir! Masanı tərk edir Thales oturur Thalesin yediyi masada ! O, süfrəni tərk edir.Biz bacardıq! Thales təkbaşına nahar etməli olsa da, məncə o, bizə qəzəblənmir :) Muteks və semafor arasında bəzi oxşarlıqlar görmüsünüz. Ümumiyyətlə, onların eyni məqsədi var: bəzi resursa girişi sinxronlaşdırmaq. Yeganə fərq ondadır ki, obyektin mutexi eyni anda yalnız bir iplə əldə edilə bilər, semafor vəziyyətində isə ip sayğacından istifadə olunur və onlardan bir neçəsi eyni anda resursa daxil ola bilir. Və bu sadəcə təsadüfi oxşarlıq deyil :) Əslində mutex tək yerli semafordur . Yəni, sayğacı ilkin olaraq 1-ə təyin edilmiş semafordur. O, həm də “ikili semafor” adlanır, çünki onun sayğacında yalnız 2 dəyər ola bilər - 1 (“pulsuz”) və 0 (“məşğul”). Hamısı budur! Gördüyünüz kimi, hər şey o qədər də çaşqın olmadığı ortaya çıxdı :) İndi İnternetdə çoxillik mövzunu daha ətraflı öyrənmək istəyirsinizsə, anlayışlar arasında naviqasiya etmək bir az daha asan olacaq. Növbəti dərslərdə görüşənədək! release()Semaphoreacquire()release()Muteks, monitor və semafor arasındakı fərq nədir - 5
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION