JavaRush /Java blogi /Random-UZ /Muteks, monitor va semafor o'rtasidagi farq nima?

Muteks, monitor va semafor o'rtasidagi farq nima?

Guruhda nashr etilgan
Salom! JavaRush-da multithreadingni o'rganayotganda siz tez-tez "mutex" va "monitor" tushunchalariga duch kelgansiz. Endi ular bir-biridan qanday farq qilishiga qaramasdan javob bera olasizmi? :) Muteks, monitor va semafor o'rtasidagi farq nima - 1Agar iloji bo'lsa, yaxshi! Agar yo'q bo'lsa (va ko'pincha bu sodir bo'ladi) - ajablanarli emas. "Muteks" va "monitor" tushunchalari haqiqatan ham bog'liq. Bundan tashqari, Internetdagi tashqi manbalarda ma'ruzalarni o'qish va ko'p mavzuli videolarni tomosha qilish paytida siz yana bir shunga o'xshash tushunchaga duch kelasiz - "semafora". Uning funksionalligi ham asosan monitor va mutexga o'xshaydi. Shuning uchun, keling, ushbu uchta atamani tushunamiz, bir nechta misollarni ko'rib chiqamiz va nihoyat, ularning bir-biridan qanday farq qilishini tushunishni boshimizda tashkil qilamiz :)

Muteks

Muteks - bu mavzularni sinxronlashtirish uchun maxsus ob'ekt. U Java-dagi har bir ob'ektga "biriktirilgan" - siz buni allaqachon bilasiz :) Standart sinflardan foydalanasizmi yoki o'z sinflaringizni yaratasizmi, farqi yo'q, aytaylik Catva Dog: barcha sinflarning barcha ob'ektlari mutexga ega . "Muteks" nomi inglizcha "MUTual Exclusion" - "o'zaro istisno" dan kelib chiqqan va bu uning maqsadini juda yaxshi aks ettiradi. Oldingi ma'ruzalardan birida aytib o'tganimizdek, mutexning vazifasi shunday mexanizmni ta'minlashdan iboratki, ma'lum bir vaqtda faqat bitta ip ob'ektga kirish huquqiga ega bo'ladi . Muteks uchun haqiqiy hayotdagi mashhur o'xshashlik "hojatxona misoli" dir. Biror kishi hojatxonaga kirganda, eshikni ichkaridan qulflaydi. Tualet bir nechta iplar orqali kirish mumkin bo'lgan ob'ekt sifatida ishlaydi. Tualet eshigidagi qulf mutexning roli, tashqaridagi odamlarning navbati esa iplarning roli. Eshikdagi qulf hojatxona mutexidir: u bir vaqtning o'zida faqat bitta odamning ichida bo'lishini ta'minlaydi. Muteks, monitor va semafor o'rtasidagi farq nima - 2Boshqacha qilib aytganda, bir vaqtning o'zida faqat bitta mavzu umumiy resurslarda ishlashi mumkin. Boshqa mavzular (odamlar) tomonidan egallab olingan resurslarga kirishga urinishlar muvaffaqiyatsizlikka uchraydi. Muteks bir nechta muhim xususiyatlarga ega. Birinchidan , faqat ikkita holat mumkin - "erkin" va "band". Bu uning qanday ishlashini tushunishni osonlashtiradi: mantiqiy o'zgaruvchilar true/false yoki ikkilik sanoq tizimi 1/0 bilan parallellar o'tkazilishi mumkin. Ikkinchidan , davlatlarni bevosita nazorat qilib bo'lmaydi. Java-da ob'ektni aniq olish, uning mutexini olish va unga kerakli holatni belgilash imkonini beradigan mexanizmlar mavjud emas. Boshqacha qilib aytganda, siz shunday qila olmaysiz:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Shunday qilib, ob'ektning mutexini chiqarib bo'lmaydi. Faqat Java mashinasi unga to'g'ridan-to'g'ri kirish huquqiga ega. Dasturchilar til vositalaridan foydalangan holda mutekslar bilan ishlaydi.

Monitor

Monitor - bu mutexga qo'shimcha "qo'shimcha". Aslida, monitor dasturchi uchun "ko'rinmas" kodning bir qismidir . Muteks haqida avvalroq gapirganda, biz oddiy misol keltirdik:
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
       }
   }
}
So'z bilan belgilangan kod blokida synchronizedob'ektimizning mutexi olinadi obj. Yaxshi, qo'lga olish sodir bo'ladi, ammo "mudofaa mexanizmi" qanday amalga oshiriladi? Nima uchun boshqa iplar so'zni ko'rganda synchronizedblok ichiga kira olmaydi ? Himoya mexanizmini yaratadigan monitor! Kompilyator so'zni synchronizedbir nechta maxsus kod qismlariga aylantiradi. Yana bir bor usul bilan misolimizga qaytaylik doSomething()va unga qo'shamiz:
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 ushbu kodni o'zgartirgandan so'ng, dasturimizning "kaput ostida" nima sodir bo'ladi:
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;
   }
}
Misol, albatta, haqiqiy emas. Bu erda, Java-ga o'xshash koddan foydalanib, biz hozir Java mashinasida nima sodir bo'layotganini aks ettirishga harakat qildik. Biroq, bu psevdokod blok ichidagi ob'ekt va iplar bilan aslida nima sodir bo'layotganini synchronizedva kompilyator bu so'zni dasturchi uchun "ko'rinmas" bo'lgan bir nechta buyruqlarga qanday o'zgartirishi haqida ajoyib tushuncha beradi. Asosan, Java-da monitor so'zi yordamida ifodalanadisynchronized . Oxirgi misoldagi so'z o'rniga paydo bo'lgan barcha kodlar synchronizedmonitordir.

Semafor

Ko'p ish zarralarini mustaqil ravishda o'rganishda siz uchragan yana bir so'z "semafora" dir. Keling, bu nima ekanligini va u monitor va mutexdan qanday farq qilishini aniqlaylik. Semafor resursga kirishni sinxronlashtirish vositasidir. Uning o'ziga xosligi shundaki, u sinxronizatsiya mexanizmini yaratishda hisoblagichdan foydalanadi. Hisoblagich umumiy manbaga bir vaqtning o'zida nechta mavzu kirishi mumkinligini aytadi. Muteks, monitor va semafor o'rtasidagi farq nima - 3Java'da semaforlar sinf bilan ifodalanadi Semaphore. Semafor obyektlarini yaratishda biz quyidagi konstruktorlardan foydalanishimiz mumkin:
Semaphore(int permits)
Semaphore(int permits, boolean fair)
Biz konstruktorga o'tamiz:
  • int permits— dastlabki va maksimal hisoblagich qiymati. Ya'ni, umumiy manbaga bir vaqtning o'zida qancha mavzu kirishi mumkin;

  • boolean fair- iplarning kirish tartibini belgilash. Agar fair= true bo'lsa , kutayotgan mavzularga ular so'ragan tartibda ruxsat beriladi. Agar u noto'g'ri bo'lsa , tartib mavzuni rejalashtiruvchi tomonidan aniqlanadi.

Semaforlardan foydalanishning klassik misoli faylasuflarning tushlik muammosidir .
Muteks, monitor va semafor o'rtasidagi farq nima - 4
Yaxshiroq tushunish uchun uning shartlarini biroz soddalashtiramiz. Tasavvur qiling-a, bizda tushlikka muhtoj 5 ta faylasuf bor. Shu bilan birga, bizda bitta stol bor va bir vaqtning o'zida ikki kishidan ortiq bo'lishi mumkin emas. Bizning vazifamiz barcha faylasuflarni oziqlantirishdir. Ularning hech biri och qolmasligi va stolga o'tirishga harakat qilganda bir-birlarini "to'sib qo'yishlari" kerak emas (biz o'likdan qochishimiz kerak). Bizning faylasuf sinfimiz shunday bo'ladi:
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-то пошло не так!");
       }
   }
}
Va bizning dasturimizni ishga tushirish uchun kod:
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();
   }
}
Biz bir vaqtning o'zida faqat ikkita faylasuf ovqatlanishi mumkin bo'lgan shartni qondirish uchun 2 soni bilan semafor yaratdik. Ya'ni, faqat ikkita ip bir vaqtning o'zida ishlashi mumkin, chunki bizning sinfimiz Philosopherdan meros bo'lib o'tgan Thread! Sinf acquire()va usullar uning ruxsat hisoblagichini boshqaradi. Usul semafordan manbaga kirish uchun ruxsat so'raydi. Agar hisoblagich > 0 bo'lsa, ruxsat beriladi va hisoblagich 1 ga kamayadi. Usul avval berilgan ruxsatni "bo'shatadi" va uni hisoblagichga qaytaradi (semaforning grant hisoblagichini 1 ga oshiradi). Dasturni ishga tushirganimizda nimaga erishamiz? Muammo hal bo‘ldimi, faylasuflarimiz o‘z navbatini kuta turib, kurashadimi? :) Bu biz olgan konsol chiqishi: Sokrat stolga o'tiradi Platon stolga o'tiradi Sokrat ovqatlangan! U stoldan chiqib ketdi, Platon ovqatlandi! U stolni tark etadi Aristotel stolga o'tiradi Pifagor Aristotel ovqatlangan stolga o'tiradi! U Pifagor yegan stoldan chiqib ketdi! U stolni tark etadi, Thales ovqatlangan stolga o'tiradi ! U stolni tark etadi.Biz muvaffaqiyatga erishdik! Va Thales yolg'iz ovqatlanishiga to'g'ri kelgan bo'lsa-da, menimcha, u bizga g'azablanmaydi :) Muteks va semafor o'rtasidagi ba'zi o'xshashliklarni sezgan bo'lishingiz mumkin. Umuman olganda, ular bir xil maqsadga ega: ba'zi manbalarga kirishni sinxronlashtirish. Yagona farq shundaki, ob'ektning mutexi bir vaqtning o'zida faqat bitta ip tomonidan olinishi mumkin, semaforda esa ip hisoblagichi ishlatiladi va ularning bir nechtasi bir vaqtning o'zida resursga kirishi mumkin. Va bu shunchaki tasodifiy o'xshashlik emas :) Aslida, mutex - bu bitta joyli semafor . Ya'ni, bu hisoblagich dastlab 1 ga o'rnatilgan semafordir. U "ikkilik semafor" deb ham ataladi, chunki uning hisoblagichi faqat 2 ta qiymatga ega bo'lishi mumkin - 1 ("bepul") va 0 ("band"). Ana xolos! Ko'rib turganingizdek, hamma narsa unchalik chalkash emas edi :) Endi, agar siz Internetda multithreading mavzusini batafsilroq o'rganmoqchi bo'lsangiz, tushunchalar bo'ylab harakatlanish sizga biroz osonroq bo'ladi. Keyingi darslarda ko'rishguncha! release()Semaphoreacquire()release()Muteks, monitor va semafor o'rtasidagi farq nima - 5
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION