Jawaban:
Semaphore bisa dihitung, sedangkan mutex hanya bisa dihitung sampai 1.
Misalkan Anda menjalankan utas yang menerima koneksi klien. Utas ini dapat menangani 10 klien secara bersamaan. Kemudian setiap klien baru mengatur semaphore hingga mencapai 10. Ketika Semaphore memiliki 10 flag, maka utas Anda tidak akan menerima koneksi baru
Mutex biasanya digunakan untuk menjaga barang. Misalkan 10 klien Anda dapat mengakses beberapa bagian sistem. Kemudian Anda dapat melindungi bagian dari sistem dengan mutex sehingga ketika 1 klien terhubung ke sub-sistem tersebut, tidak ada orang lain yang memiliki akses. Anda dapat menggunakan Semaphore untuk tujuan ini juga. Mutex adalah "Mutual Exclusion Semaphore" .
ReentrantLock
. Semua ini rekursif. Saya tidak mengetahui adanya contoh "dunia nyata" dari mutex non-rekursif (saya telah melihatnya hanya di buku teks) jadi saya tidak mempertimbangkannya.
Sayangnya semua orang telah melewatkan perbedaan terpenting antara semaphore dan mutex; konsep " kepemilikan ".
Semaphore tidak memiliki gagasan tentang kepemilikan, ini berarti bahwa setiap utas dapat melepaskan semaphore (ini dapat menyebabkan banyak masalah tetapi dapat membantu dengan "deteksi kematian"). Sedangkan mutex memang memiliki konsep kepemilikan (yaitu Anda hanya dapat merilis mutex yang Anda peroleh).
Kepemilikan sangat penting untuk pemrograman sistem konkuren yang aman. Saya akan selalu merekomendasikan menggunakan mutex sebagai preferensi ke semaphore (tetapi ada implikasi kinerja).
Mutex juga dapat mendukung pewarisan prioritas (yang dapat membantu dengan masalah inversi prioritas) dan rekursi (menghilangkan satu jenis kebuntuan).
Juga harus ditunjukkan bahwa ada semaphore "biner" dan semaphore "hitung / umum". Semaphore Java adalah semaphore penghitungan dan dengan demikian memungkinkannya untuk diinisialisasi dengan nilai yang lebih besar dari satu (sedangkan, seperti yang ditunjukkan, mutex hanya dapat menghitung konseptual satu). Kegunaan ini telah disorot di posting lain.
Jadi untuk meringkas, kecuali Anda memiliki banyak sumber daya untuk dikelola, saya akan selalu merekomendasikan mutex di atas semaphore.
Mutex pada dasarnya adalah pengecualian timbal balik. Hanya satu utas yang dapat memperoleh sumber daya sekaligus. Saat satu utas memperoleh sumber daya, tidak ada utas lain yang diizinkan untuk memperoleh sumber daya sampai utas yang memiliki sumber daya dirilis. Semua utas yang menunggu untuk memperoleh sumber daya akan diblokir.
Semaphore digunakan untuk mengontrol jumlah thread yang dieksekusi. Akan ada serangkaian sumber daya yang tetap. Jumlah resource akan berkurang setiap kali thread memiliki yang sama. Ketika jumlah semaphore mencapai 0 maka tidak ada utas lain yang diizinkan untuk mendapatkan sumber daya. Utas diblokir sampai utas lain yang memiliki rilis sumber daya.
Singkatnya, perbedaan utamanya adalah berapa banyak utas yang diizinkan untuk memperoleh sumber daya sekaligus?
Mutex digunakan untuk akses serial ke sumber daya sementara semaphore membatasi akses ke sumber daya hingga nomor yang ditetapkan. Anda dapat menganggap mutex sebagai semaphore dengan jumlah akses 1. Apa pun yang Anda setel jumlah semaphore Anda, thread itu dapat mengakses sumber daya sebelum sumber daya diblokir.
Semaphore adalah mekanisme sinkronisasi penghitungan, sedangkan mutex tidak.
Pertanyaan ini memiliki jawaban yang relevan dan tautan ke panduan resmi Java: Apakah ada Mutex di Java?
Semafor penghitungan. Secara konseptual, semaphore memiliki satu set izin. Setiap
acquire()
blok jika perlu sampai izin tersedia, dan kemudian mengambilnya. Masing-masingrelease()
menambahkan izin, berpotensi melepaskan pengakuisisi pemblokiran. Namun, sebenarnya tidak ada objek izin yang digunakan; Semaphore hanya menyimpan hitungan jumlah yang tersedia dan bertindak sesuai dengan itu.
Semaphore sering digunakan untuk membatasi jumlah utas daripada yang dapat mengakses beberapa sumber daya (fisik atau logis)
Java tidak memiliki API Mutex bawaan. Tapi itu bisa diimplementasikan sebagai semaphore biner.
Semaphore yang diinisialisasi ke satu, dan yang digunakan sedemikian rupa sehingga hanya memiliki paling banyak satu izin yang tersedia, dapat berfungsi sebagai kunci pengecualian bersama. Ini lebih dikenal sebagai semaphore biner, karena hanya memiliki dua status: satu izin tersedia, atau nol izin tersedia.
Ketika digunakan dengan cara ini, semaphore biner memiliki properti (tidak seperti banyak implementasi Lock), bahwa "kunci" dapat dilepaskan oleh utas selain pemilik (karena semaphore tidak memiliki gagasan tentang kepemilikan) . Ini dapat berguna dalam beberapa konteks khusus, seperti pemulihan kebuntuan.
Jadi perbedaan utama antara Semaphore dan Mutex:
Semaphore membatasi jumlah utas untuk mengakses sumber daya melalui izin. Mutex hanya mengizinkan satu utas untuk mengakses sumber daya.
Tidak ada utas yang memiliki Semaphore. Thread dapat memperbarui jumlah izin dengan memanggil acquire()
dan release()
metode. Mutex harus dibuka hanya dengan benang yang menahan kunci.
Ketika mutex digunakan dengan variabel kondisi, ada bracketing tersirat — jelas bagian mana dari program yang dilindungi . Ini belum tentu berlaku untuk semaphore, yang dapat disebut sebagai pemrograman konkuren pergi ke —itu kuat tetapi terlalu mudah digunakan dengan cara yang tidak terstruktur dan tidak pasti.
Mutex adalah semaphore biner. Harus diinisialisasi dengan 1, agar prinsip First Come First Serve terpenuhi. Ini membawa kita ke properti khusus lainnya dari setiap mutex: orang yang turun , pasti orang yang naik . Ergo, kami telah memperoleh pengecualian timbal balik atas beberapa sumber daya.
Sekarang Anda dapat melihat bahwa mutex adalah kasus khusus dari semaphore umum.
Objek sinkronisasi Semaphoremenerapkan lampu lalu lintas klasik. Lampu lalu lintas mengontrol akses ke sumber daya yang dibagikan oleh penghitung. Jika penghitung lebih besar dari nol, akses diberikan; Jika nol, akses ditolak. Penghitung menghitung izin yang memungkinkan akses ke sumber daya bersama. Kemudian, untuk mengakses sumber daya, utas harus mendapat izin dari lampu lalu lintas. Secara umum, untuk menggunakan lampu lalu lintas, utas yang ingin mengakses sumber daya bersama mencoba mendapatkan izin. Jika jumlah lampu lalu lintas lebih besar dari nol, utas memperoleh izin, dan jumlah lampu lalu lintas berkurang. Jika tidak, utas akan terkunci hingga mendapat izin. Saat utas tidak lagi perlu mengakses sumber daya bersama, utas melepaskan izin, sehingga jumlah lampu lalu lintas meningkat. Jika ada utas lain yang menunggu izin, itu memperoleh izin pada saat itu. Kelas Semaphore Java mengimplementasikan mekanisme ini.
Semaphore memiliki dua pembangun:
Semaphore(int num)
Semaphore(int num, boolean come)
num menentukan hitungan awal izin. Kemudian num menentukan jumlah utas yang dapat mengakses sumber daya bersama pada waktu tertentu. Jika num adalah satu, ia dapat mengakses sumber daya satu utas dalam satu waktu. Dengan menyetel come as true, Anda dapat menjamin bahwa utas yang Anda tunggu diberikan izin sesuai urutan yang mereka minta.
Anda membandingkan yang tak tertandingi, secara teknis tidak ada perbedaan antara Semaphore dan mutex yang tidak masuk akal. Mutex hanyalah nama penting seperti nama apa pun dalam logika aplikasi Anda, itu berarti Anda menginisialisasi semaphore di "1", ini biasanya digunakan untuk melindungi sumber daya atau variabel yang dilindungi untuk memastikan pengecualian bersama.