JavaRush /Java Blog /Random-ID /Apa perbedaan antara mutex, monitor dan semaphore

Apa perbedaan antara mutex, monitor dan semaphore

Dipublikasikan di grup Random-ID
Halo! Saat mempelajari multithreading di JavaRush, Anda sering menemukan konsep “mutex” dan “monitor”. Bisakah Anda sekarang, tanpa mengintip, menjawab perbedaannya? :) Apa perbedaan antara mutex, monitor dan semaphore - 1Jika Anda bisa, bagus sekali! Jika tidak (dan paling sering ini terjadi) - tidak heran. Konsep "mutex" dan "monitor" memang saling berkaitan. Selain itu, saat membaca ceramah dan menonton video tentang multithreading pada sumber daya eksternal di Internet, Anda akan menemukan konsep serupa lainnya - “semaphore”. Fungsionalitasnya juga sebagian besar mirip dengan monitor dan mutex. Oleh karena itu, mari kita pahami ketiga istilah ini, lihat beberapa contoh, dan terakhir susun di kepala kita pemahaman tentang perbedaannya satu sama lain :)

muteks

Mutex adalah objek khusus untuk menyinkronkan thread. Itu "melekat" ke setiap objek di Java - Anda sudah mengetahuinya :) Tidak masalah apakah Anda menggunakan kelas standar atau membuat kelas Anda sendiri, misalnya, Catdan Dog: semua objek dari semua kelas memiliki mutex . Nama "mutex" berasal dari bahasa Inggris "MUTual EXclusion" - "mutual exclusion", dan ini mencerminkan tujuannya dengan sempurna. Seperti yang kami katakan di salah satu kuliah sebelumnya, tugas mutex adalah menyediakan mekanisme sehingga hanya satu thread yang memiliki akses ke suatu objek pada waktu tertentu . Analogi populer untuk mutex dalam kehidupan nyata adalah “contoh toilet”. Ketika seseorang memasuki toilet, dia mengunci pintu dari dalam. Toilet bertindak sebagai objek yang dapat diakses oleh banyak thread. Kunci pintu toilet berperan sebagai mutex, dan antrian orang di luar berperan sebagai benang. Kunci pintunya adalah mutex toilet: yang memastikan hanya satu orang yang bisa berada di dalam pada satu waktu. Apa perbedaan antara mutex, monitor dan semaphore - 2Dengan kata lain, hanya satu thread dalam satu waktu yang dapat bekerja pada sumber daya bersama. Upaya thread lain (orang) untuk mengakses sumber daya yang ditempati akan gagal. Mutex memiliki beberapa fitur penting. Pertama , hanya ada dua keadaan yang memungkinkan - “bebas” dan “sibuk”. Hal ini memudahkan untuk memahami cara kerjanya: persamaan dapat digambar dengan variabel Boolean benar/salah atau sistem bilangan biner 1/0. Kedua , negara tidak dapat dikontrol secara langsung. Tidak ada mekanisme di Java yang memungkinkan Anda mengambil objek secara eksplisit, mendapatkan mutexnya, dan menetapkan status yang diinginkan padanya. Dengan kata lain, Anda tidak dapat melakukan sesuatu seperti:
Object myObject = new Object();
Mutex mutex = myObject.getMutex();
mutex.free();
Dengan demikian, mutex objek tidak dapat dilepaskan. Hanya mesin Java yang memiliki akses langsung ke sana. Pemrogram bekerja dengan mutex menggunakan alat bahasa.

Memantau

Monitor adalah “tambahan” tambahan untuk mutex. Faktanya, monitor adalah sepotong kode yang “tidak terlihat” oleh pemrogram . Berbicara tentang mutex tadi, kami memberikan contoh sederhana:
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
       }
   }
}
Dalam blok kode yang ditandai dengan kata tersebut synchronized, mutex objek kita ditangkap obj. Oke, penangkapan memang terjadi, tapi bagaimana sebenarnya “mekanisme pertahanan” tersebut dicapai? synchronizedMengapa utas lain tidak bisa masuk ke dalam blok ketika mereka melihat sebuah kata ? Monitorlah yang menciptakan mekanisme perlindungan! Kompiler mengubah kata tersebut synchronizedmenjadi beberapa bagian kode khusus. Sekali lagi mari kita kembali ke contoh kita dengan metode ini doSomething()dan menambahkannya:
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();
       }
   }
}
Inilah yang akan terjadi "di balik terpal" program kita setelah kompiler mengonversi kode ini:
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;
   }
}
Contohnya tentu saja tidak nyata. Di sini, dengan menggunakan kode mirip Java, kami mencoba merefleksikan apa yang terjadi saat ini di dalam mesin Java. Namun, kodesemu ini memberikan pemahaman yang baik tentang apa yang sebenarnya terjadi dengan objek dan thread di dalam blok synchronizeddan bagaimana kompiler mengubah kata ini menjadi beberapa perintah yang “tidak terlihat” oleh pemrogram. Intinya, monitor di Java dinyatakan menggunakan katasynchronized . Semua kode yang muncul sebagai pengganti kata synchronizedpada contoh terakhir adalah monitor.

Tiang sinyal

Kata lain yang Anda temui saat mempelajari multithreading sendiri adalah “semaphore”. Mari kita cari tahu apa itu dan apa bedanya dengan monitor dan mutex. Semaphore adalah sarana untuk menyinkronkan akses ke sumber daya. Keunikannya adalah ia menggunakan penghitung saat membuat mekanisme sinkronisasi. Penghitung memberi tahu kita berapa banyak thread yang dapat mengakses sumber daya bersama secara bersamaan. Apa perbedaan antara mutex, monitor dan semaphore - 3Semaphore di Java diwakili oleh kelas Semaphore. Saat membuat objek semaphore, kita dapat menggunakan konstruktor berikut:
Semaphore(int permits)
Semaphore(int permits, boolean fair)
Kami meneruskan ke konstruktor:
  • int permits— nilai penghitung awal dan maksimum. Artinya, berapa banyak thread yang dapat mengakses sumber daya bersama secara bersamaan;

  • boolean fair- untuk menetapkan urutan thread yang akan menerima akses. Jika fair= true , akses diberikan ke thread yang menunggu sesuai urutan permintaannya. Jika salah , urutannya akan ditentukan oleh penjadwal thread.

Contoh klasik penggunaan semaphore adalah masalah filsuf makan siang .
Apa perbedaan antara mutex, monitor dan semaphore - 4
Kami akan menyederhanakan persyaratannya sedikit untuk pemahaman yang lebih baik. Bayangkan kita memiliki 5 filsuf yang butuh makan siang. Pada saat yang sama, kami memiliki satu meja, dan tidak lebih dari dua orang dapat berada di meja tersebut pada waktu yang bersamaan. Tugas kita adalah memberi makan semua filsuf. Tak satu pun dari mereka harus kelaparan, dan mereka juga tidak boleh “menghalangi” satu sama lain ketika mencoba untuk duduk di meja (kita harus menghindari kebuntuan). Seperti inilah kelas filsuf kita nantinya:
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-то пошло не так!");
       }
   }
}
Dan berikut ini kode untuk menjalankan program kita:
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();
   }
}
Kami membuat semaphore dengan hitungan 2 untuk memenuhi syarat bahwa hanya dua filsuf yang bisa makan pada saat yang bersamaan. Artinya, hanya dua thread yang dapat bekerja secara bersamaan, karena kelas kita Philosopherdiwarisi dari Thread! Kelas acquire()dan metode mengontrol penghitung izinnya. Metode ini meminta izin untuk mengakses sumber daya dari semaphore. Jika penghitung > 0, izin diberikan dan penghitung dikurangi 1. Metode "melepaskan" izin yang diberikan sebelumnya dan mengembalikannya ke penghitung (menambah penghitung hibah semafor sebesar 1). Apa yang kita dapatkan ketika kita menjalankan program tersebut? Apakah masalahnya sudah terpecahkan? Akankah para filosof kita berjuang sambil menunggu giliran? :) Ini adalah output konsol yang kami terima: Socrates duduk di meja Plato duduk di meja yang Socrates makan! Dia meninggalkan meja. Plato sudah makan! Dia meninggalkan meja yang diduduki Aristoteles di meja yang diduduki Pythagoras di meja yang telah dimakan Aristoteles! Dia meninggalkan meja yang telah dimakan Pythagoras! Dia meninggalkan meja yang Thales duduk di meja yang Thales makan! Dia meninggalkan meja. Kita berhasil! Dan meskipun Thales harus makan sendirian, menurut saya dia tidak marah pada kami :) Anda mungkin telah memperhatikan beberapa kesamaan antara mutex dan semaphore. Secara umum, mereka memiliki tujuan yang sama: untuk menyinkronkan akses ke beberapa sumber daya. Satu-satunya perbedaan adalah bahwa mutex suatu objek hanya dapat diperoleh oleh satu thread pada satu waktu, sedangkan dalam kasus semaphore, penghitung thread digunakan, dan beberapa dari mereka dapat mengakses sumber daya sekaligus. Dan ini bukan hanya kesamaan yang kebetulan :) Faktanya, mutex adalah semaphore satu tempat . Artinya, ini adalah semafor yang penghitungnya awalnya disetel ke 1. Disebut juga "semafor biner" karena penghitungnya hanya dapat memiliki 2 nilai - 1 ("bebas") dan 0 ("sibuk"). Itu saja! Seperti yang Anda lihat, semuanya ternyata tidak terlalu membingungkan :) Sekarang, jika Anda ingin mempelajari topik multithreading lebih detail di Internet, akan lebih mudah bagi Anda untuk menavigasi konsepnya. Sampai jumpa di pelajaran selanjutnya! release()Semaphoreacquire()release()Apa perbedaan antara mutex, monitor dan semaphore - 5
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION