JavaRush /Java блогу /Random-KY /Мутекс, монитор жана семафордун ортосунда кандай айырма б...

Мутекс, монитор жана семафордун ортосунда кандай айырма бар

Группада жарыяланган
Салам! JavaRushте көп агымды окуп жүрүп, сиз көп учурда "мутекс" жана "монитор" түшүнүктөрүнө туш болосуз. Эми карап туруп, алардын кандайча айырмаланганына жооп бере аласызбы? :) Мутекс, монитор жана семафордун ортосунда кандай айырма бар - 1Колдон келсе, молодец! Эгерде жок болсо (жана көбүнчө мындай болот) - таң калыштуу эмес. "Мутекс" жана "монитор" түшүнүктөрү чындап эле байланыштуу. Мындан тышкары, Интернетте тышкы ресурстардан лекцияларды окуп, көп темалуу видеолорду көрүп жатып, сиз дагы бир окшош түшүнүккө - "семафорага" туш болосуз. Анын функционалдуулугу да негизинен монитор менен мутекске окшош. Ошондуктан, келгиле, бул үч терминди түшүнүп, бир нече мисалдарды карап көрөлү жана акыры алардын бири-биринен кандайча айырмаланарын түшүнүүнү башыбызда уюштуралы :)

Mutex

Мутекс жиптерди синхрондоштуруу үчүн атайын an object болуп саналат. Ал Javaдагы ар бир an objectке "тиркелет" - сиз буга чейин эле билесизби :) Сиз стандарттуу класстарды колдоносузбу же өзүңүздүн класстарыңызды түзөсүзбү, айырмасы жок, айталы Cat: Dogбардык класстардын бардык an objectилеринде мутекс бар . "Мутекс" аталышы англисче "MUTual Exclusion" - "өз ара алып салуу" сөзүнөн келип чыккан жана бул анын максатын эң сонун чагылдырат. Мурунку лекциялардын биринде айткандай, мутекстин милдети белгилүү бир убакта an objectке бир гана жип кире алгыдай механизмди камсыз кылуу болуп саналат . Чыныгы жашоодо мутекстин популярдуу окшоштугу - бул "туалеттин мисалы". Адам ажатканага киргенде эшикти ичинен бекитет. Туалет бир нече жип менен кире турган an object катары иштейт. Туалеттин эшигинин кулпусу мутекстин ролу, ал эми сырттагы адамдардын кезеги жиптердин ролу. Эшиктеги кулпу туалеттин мутекси болуп саналат: ал бир эле учурда бир гана адамдын ичинде болушун камсыздайт. Мутекс, монитор жана семафордун ортосунда кандай айырма бар - 2Башка сөз менен айтканда, бир эле учурда бир гана жип бөлүшүлгөн ресурстарда иштей алат. Башка жиптердин (адамдардын) ээлеген ресурстарга кирүү аракети ишке ашпай калат. Мутекс бир нече маанилүү өзгөчөлүктөргө ээ. Биринчиден , эки гана мамлекет болушу мүмкүн - "эркин" жана "бос". Бул анын кантип иштээрин түшүнүүнү жеңилдетет: логикалык өзгөрмөлөр true/false же экorк санауу системасы 1/0 менен параллелдерди түзсө болот. Экинчиден , мамлекеттерди түз көзөмөлдөй алbyte. Javaда an objectти так алып, анын мутексин алууга жана ага каалаган статусту ыйгарууга мүмкүндүк берүүчү механизмдер жок. Башкача айтканда, сиз төмөнкүдөй нерсени кыла албайсыз:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Ошентип, an objectтин мутексин чыгарууга болбойт. 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блоктун ичине кире алbyte ? Бул коргоо механизмин түзүүчү монитор! Компилятор сөздү 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 тorнде монитор деген сөз менен туюнтулганsynchronized . synchronizedАкыркы мисалдагы сөздүн ордуна пайда болгон бардык code - бул монитор.

Семафор

Көп агымды өз алдынча үйрөнүп жатканда жолуккан дагы бир сөз "семафора". Келгиле, бул эмне экенин жана монитор менен мутекстен эмнеси менен айырмаланарын аныктап көрөлү. Семафор бул ресурска кирүү мүмкүнчүлүгүн синхрондоштуруунун каражаты. Анын өзгөчөлүгү синхрондоштуруу механизмин түзүүдө эсептегичти колдонот. Эсептегич бизге канча жип бир эле учурда жалпы ресурска кире аларын айтат. Мутекс, монитор жана семафордун ортосунда кандай айырма бар - 3Java тorндеги семафорлор класс менен көрсөтүлөт Semaphore. Семафордук an objectтерди түзүүдө биз төмөнкү конструкторлорду колдоно алабыз:
Semaphore(int permits)
Semaphore(int permits, boolean fair)
Биз конструкторго өтөбүз:
  • int permits— баштапкы жана максималдуу эсептегич маани. Башкача айтканда, канча жип бир эле учурда жалпы ресурска кире алат;

  • boolean fair- жиптердин кирүү тартибин орнотуу. Эгерде fair= true болсо , жетүү күтүп жаткан жиптерге алар сураган тартипте берилет. Эгер ал false болсо , тартип жип пландоочусу тарабынан аныкталат.

Семафорлорду колдонуунун классикалык мисалы - философтордун түшкү тамак маселеси .
Мутекс, монитор жана семафордун ортосунда кандай айырма бар - 4
Биз жакшыраак түшүнүү үчүн анын шарттарын бир аз жөнөкөйлөтөбүз. Элестеткиле, бизде түшкү тамакка муктаж 5 философ бар. Ошол эле учурда бизде бир стол бар, ага бир эле учурда экиден ашык адам отура алbyte. Биздин милдет бардык философторду багуу. Экөө тең ачка калбашы керек, дасторконго отурууга аракет кылганда бири-бирин «бөгөт» албашы керек (биз туюктан качышыбыз керек). Биздин философ классыбыз ушундай болот:
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ге көбөйтүү). Программаны иштеткенде эмне алабыз? Маселе чечилдиби, биздин философтор кезек күтүп туруп күрөшө беришеби? :) Бул биз алган консолдун чыгарылышы: Сократ столго отурат Платон столго отурат Сократ жеген! Ал дасторкондон чыгып кетти.Платон жеди! Ал столду таштап Аристотель столго отурат Пифагор Аристотель жеген дасторконго отурат! Ал Пифагор жеген дасторкондон чыгып кетти! Ал дасторкондон чыгып кетти Талес Талес жеген столго отурат ! Ал дасторкондон чыгып кетти.Биз ийгorкке жеттик! Фалес жалгыз тамактанышы керек болсо да, менимче, ал бизге жинденген жок :) Сиз мутекс менен семафордун окшоштуктарын байкаган чыгарсыз. Жалпысынан алганда, алардын бир эле максаты бар: кандайдыр бир ресурска кирүү мүмкүнчүлүгүн синхрондоштуруу. Бир гана айырмасы, an objectтин мутексин бир эле учурда бир жип менен гана алууга болот, ал эми семафор үчүн жип эсептегич колдонулат жана алардын бир нечеси бир эле учурда ресурска кире алат. Жана бул жөн эле кокустук окшоштук эмес :) Чынында, мутекс - бул бир орундуу семафор . Башкача айтканда, бул эсептегич башында 1ге коюлган семафор. Ал "экorк семафор" деп да аталат, анткени анын эсептегичинде 2 гана маани болушу мүмкүн - 1 ("эркин") жана 0 ("бос"). Баары болду! Көрүнүп тургандай, баары анчалык деле баш аламан эмес болуп чыкты :) Эми, эгер сиз Интернетте көп агым темасын кененирээк изилдегиңиз келсе, анда түшүнүктөрдү башкаруу сизге бир аз жеңилдейт. Кийинки сабактарда көрүшкөнчө! release()Semaphoreacquire()release()Мутекс, монитор жана семафордун ортосунда кандай айырма бар - 5
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION