JavaRush /Java блогы /Random-KK /Мутекс, монитор және семафордың айырмашылығы неде

Мутекс, монитор және семафордың айырмашылығы неде

Топта жарияланған
Сәлеметсіз бе! JavaRush-те көп ағынды оқу барысында сіз «мутекс» және «монитор» ұғымдарын жиі кездестірдіңіз. Енді қарап отырмай, олардың қалай ерекшеленетініне жауап бере аласыз ба? :) Мутекс, монитор және семафордың айырмашылығы неде - 1Қолыңнан келсе, жарайсың! Егер жоқ болса (және бұл жиі орын алады) - таңқаларлық емес. «Мутекс» және «монитор» ұғымдары шынымен де байланысты. Сонымен қатар, Интернеттегі сыртқы ресурстарда лекцияларды оқу және мультиағынды бейнелерді көру кезінде сіз тағы бір ұқсас ұғымды кездестіресіз - «семафор». Оның функционалдығы да негізінен монитор мен мутекске ұқсас. Сондықтан, осы үш терминді түсініп, бірнеше мысалдарды қарастырайық және соңында олардың бір-бірінен қалай ерекшеленетінін түсінуді ұйымдастырайық :)

Мутекс

Мутекс – ағындарды синхрондау үшін арнайы нысан. Ол Java тіліндегі әрбір нысанға «тіркелген» - сіз мұны әлдеқашан білесіз :) Стандартты сыныптарды пайдаланасыз ба немесе өз сыныптарыңызды жасағаныңыз маңызды емес, айталық Cat: Dogбарлық сыныптардың барлық нысандарында мутекс бар . «Мутекс» атауы ағылшын тіліндегі «MUTual Exclusion» - «өзара алып тастау» сөзінен шыққан және бұл оның мақсатын тамаша көрсетеді. Алдыңғы дәрістердің бірінде айтқанымыздай, мутекстің міндеті белгілі бір уақытта an objectіге тек бір ағынның қол жеткізе алатындай механизмді қамтамасыз ету болып табылады . Мутекс үшін танымал өмірдегі ұқсастық - «дәретхана үлгісі». Адам дәретханаға кіргенде есікті ішінен құлыптайды. Дәретхана бірнеше ағындар арқылы қол жеткізуге болатын нысан ретінде әрекет етеді. Дәретхана есігіндегі құлып - мутекс рөлі, ал сырттағы адамдардың кезегі - жіптердің рөлі. Есік құлпы дәретхана мутексі болып табылады: ол бір уақытта тек бір адамның ішінде болуын қамтамасыз етеді. Мутекс, монитор және семафордың айырмашылығы неде - 2Басқаша айтқанда, ортақ ресурстарда бір уақытта тек бір ағын жұмыс істей алады. Басқа ағындардың (адамдардың) басып алынған ресурстарға қол жеткізу әрекеттері сәтсіз болады. Мутекстің бірнеше маңызды ерекшеліктері бар. Біріншіден , тек екі күй болуы мүмкін - «бос» және «бос емес». Бұл оның қалай жұмыс істейтінін түсінуді жеңілдетеді: логикалық айнымалылар true/false немесе екілік санау жүйесі 1/0 арқылы параллельдер салуға болады. Екіншіден , мемлекеттерді тікелей басқару мүмкін емес. Java тілінде нысанды нақты алуға, оның мутексін алуға және оған қажетті күйді тағайындауға мүмкіндік беретін механизмдер жоқ. Басқаша айтқанда, сіз келесідей нәрсені жасай алмайсыз:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Осылайша, нысанның мутексін босату мүмкін емес. Оған тек Java құрылғысы тікелей қол жеткізе алады. Бағдарламашылар тілдік құралдарды пайдалана отырып, мутекстермен жұмыс істейді.

Монитор

Монитор – мутекске қосымша «қондырма». Шын мәнінде, монитор бағдарламашы үшін «көрінбейтін» code бөлігі болып табылады . Жоғарыда мутекс туралы айтатын болсақ, біз қарапайым мысал келтірдік:
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
       }
   }
}
Сөзбен белгіленген code блогында synchronizedбіздің an objectіміздің мутексі түсіріледі obj. Жарайды, басып алу орын алады, бірақ «қорғаныс механизміне» қалай қол жеткізілді? Неліктен басқа ағындар сөзді көргенде synchronizedблоктың ішіне кіре алмайды ? Бұл қорғаныс механизмін жасайтын монитор! Компилятор сөзді synchronizedбірнеше арнайы code бөліктеріне түрлендіреді. Әдіспен мысалға тағы да оралайық doSomething()және оған қосамыз:
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();
       }
   }
}
Компилятор осы codeты түрлендіргеннен кейін бағдарламамыздың «қақпағы астында» не болады:
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;
   }
}
Мысал, әрине, нақты емес. Мұнда Java-ға ұқсас codeты қолдана отырып, біз Java машинасының ішінде осы сәтте не болып жатқанын көрсетуге тырыстық. Дегенмен, бұл псевдоcode блок ішіндегі an object пен ағындармен шын мәнінде не болып жатқанын synchronizedжәне компилятор бұл сөзді бағдарламашыға «көрінбейтін» бірнеше командаларға қалай түрлендіретінін жақсы түсінуге мүмкіндік береді. Негізінде, Java тіліндегі монитор сөзі арқылы көрсетіледіsynchronized . synchronizedСоңғы мысалдағы сөздің орнына пайда болған барлық code монитор болып табылады.

Семафор

Көп ағынды оқуды өз бетіңізше оқыған кезде кездесетін тағы бір сөз – «семафор». Оның не екенін және оның монитор мен мутекстен айырмашылығы неде екенін анықтайық. Семафор – ресурсқа қол жеткізуді синхрондау құралы. Оның ерекшелігі синхрондау механизмін құру кезінде есептегішті пайдаланады. Есептегіш ортақ ресурсқа қанша ағынның бір уақытта қол жеткізе алатынын айтады. Мутекс, монитор және семафордың айырмашылығы неде - 3Java тіліндегі семафорлар сыныппен ұсынылған Semaphore. Семафорлық нысандарды құру кезінде біз келесі конструкторларды пайдалана аламыз:
Semaphore(int permits)
Semaphore(int permits, boolean fair)
Біз конструкторға өтеміз:
  • int permits— бастапқы және максималды санауыш мәні. Яғни, ортақ ресурсқа қанша ағын бір уақытта қол жеткізе алады;

  • boolean fair- ағындардың рұқсат алу ретін орнату. Егер fair= true болса , рұқсат күту ағындарына олар сұраған ретпен беріледі. Егер ол false болса , ретті ағынды жоспарлаушы анықтайды.

Семафорларды пайдаланудың классикалық мысалы - философтардың түскі ас мәселесі .
Мутекс, монитор және семафордың айырмашылығы неде - 4
Жақсырақ түсіну үшін оның шарттарын сәл жеңілдетеміз. Елестетіп көріңізші, бізде түскі асқа мұқтаж 5 философ бар. Бұл ретте бізде бір үстел бар, оған бір уақытта екі адамнан артық отыра алмайды. Біздің міндетіміз – барлық философтарды тамақтандыру. Олардың ешқайсысы аш қалмауы керек, үстелге отыруға тырысқанда бір-бірін «бұғаттау» керек (біз тығырықтан аулақ болуымыз керек). Біздің философтар класы келесідей болады:
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-то пошло не так!");
       }
   }
}
Міне, біздің бағдарламаны іске қосу үшін code:
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();
   }
}
Біз тек екі философ бір уақытта тамақ іше алады деген шартты қанағаттандыру үшін 2 саны бар семафор құрдық. Яғни, тек екі ағын бір уақытта жұмыс істей алады, өйткені біздің класс Philosopher-дан мұраланған Thread! Класс acquire()пен әдістер оның рұқсат есептегішін басқарады. Әдіс семафордан ресурсқа кіру рұқсатын сұрайды. Егер санауыш > 0 болса, рұқсат беріледі және санауыш 1-ге азайтылады. Әдіс бұрын берілген рұқсатты «шығарады» және оны есептегішке қайтарады (семафордың рұқсат санауышын 1-ге көбейтеді). Бағдарламаны іске қосқанда не аламыз? Мәселе шешілді ме?Біздің философтар өз кезегін күтіп тұрып күресе ме? :) Бұл біз алған консоль шығысы: Сократ үстелге отырады Платон Сократ жеген үстелге отырады! Ол үстелден шығып кетті.Платон жеп қойды! Ол үстелден шығады Аристотель үстелге отырады Пифагор Аристотель жеген үстелге отырады! Ол Пифагор жеген үстелден шығып кетті! Ол үстелден шығады Талес Талес жеген үстелге отырады ! Ол үстелден шығып кетеді.Біз табысқа жеттік! Талеске жалғыз түскі ас ішуге тура келсе де, менің ойымша, ол бізге ренжімейді :) Мутекс пен семафор арасындағы кейбір ұқсастықтарды байқаған боларсыз. Жалпы, олардың мақсаты бір: кейбір ресурсқа қол жеткізуді синхрондау. Жалғыз айырмашылық an objectінің мутексін бір уақытта тек бір ағынмен алуға болады, ал семафор жағдайында ағынды есептегіш пайдаланылады және олардың бірнешеуі ресурсқа бірден қол жеткізе алады. Және бұл жай ғана кездейсоқ ұқсастық емес :) Шын мәнінде, мутекс - бұл бір орындық семафор . Яғни, бұл есептегіші бастапқыда 1-ге орнатылған семафор. Оны «екілік семафор» деп те атайды, өйткені оның есептегішінде тек 2 мән болуы мүмкін - 1 («бос») және 0 («бос емес»). Осымен болды! Көріп отырғаныңыздай, бәрі соншалықты түсініксіз болып шықты :) Енді, егер сіз Интернетте көп ағынды тақырыпты толығырақ зерттегіңіз келсе, сізге түсініктерді шарлау оңайырақ болады. Келесі сабақтарда кездескенше! release()Semaphoreacquire()release()Мутекс, монитор және семафордың айырмашылығы неде - 5
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION