Yanıtlar:
Semafor sayılabilirken muteks yalnızca 1'e kadar sayılabilir.
İstemci bağlantılarını kabul eden bir iş parçacığınızın olduğunu varsayalım. Bu iş parçacığı aynı anda 10 istemciyi idare edebilir. Sonra her yeni istemci semaforu 10'a ulaşana kadar ayarlar. Semaforda 10 bayrak olduğunda, iş parçacığınız yeni bağlantıları kabul etmez.
Muteks genellikle eşyaları korumak için kullanılır. 10 istemcinizin sistemin birden çok bölümüne erişebileceğini varsayalım. Daha sonra bir muteks ile sistemin bir bölümünü koruyabilirsiniz, böylece bu alt sisteme 1 istemci bağlandığında, başka hiç kimsenin erişimi olmamalıdır. Bu amaçla bir Semafor da kullanabilirsiniz. Muteks bir "Karşılıklı Dışlama Semaforudur" .
ReentrantLock
. Bunların hepsi yinelemeli. Yinelemeli olmayan mutekslerin "gerçek dünya" örneklerinden haberdar olmadığım için (onları sadece ders kitaplarında gördüm), bu yüzden onları dikkate almadım.
Maalesef semafor ve muteks arasındaki en önemli farkı herkes gözden kaçırmıştır; " mülkiyet " kavramı .
Semaforların sahiplik kavramı yoktur, bu, herhangi bir iş parçacığının bir semafor yayınlayabileceği anlamına gelir (bu, kendi içinde birçok soruna yol açabilir, ancak "ölüm tespiti" ile yardımcı olabilir). Oysa bir muteks sahiplik kavramına sahipse (yani, yalnızca edindiğiniz bir muteksi serbest bırakabilirsiniz).
Sahiplik, eşzamanlı sistemlerin güvenli programlanması için inanılmaz derecede önemlidir. Semafor yerine muteks kullanılmasını her zaman tavsiye ederim (ancak performans çıkarımları var).
Muteksler ayrıca öncelikli kalıtımı (öncelikli ters çevirme problemine yardımcı olabilir) ve özyinelemeyi (bir tür kilitlenmeyi ortadan kaldırarak) destekleyebilir.
Ayrıca "ikili" semaforlar ve "sayma / genel" semaforlar olduğu da belirtilmelidir. Java'nın semaforu bir sayma semaforudur ve bu nedenle birden büyük bir değerle başlatılmasına izin verir (oysa, belirtildiği gibi, bir muteks yalnızca bir kavramsal sayabilir). Bunun faydası diğer yazılarda belirtilmiştir.
Özetlemek gerekirse, yönetecek birden fazla kaynağınız yoksa, semafor yerine her zaman muteksi öneririm.
Mutex temelde karşılıklı dışlamadır. Tek seferde yalnızca bir iş parçacığı kaynağı alabilir. Bir iş parçacığı kaynağı aldığında, kaynağa sahip olan iş parçacığı serbest bırakılıncaya kadar başka hiçbir iş parçacığının kaynağı almasına izin verilmez. Kaynak almayı bekleyen tüm iş parçacıkları engellenecektir.
Semafor, yürütülen iş parçacığı sayısını kontrol etmek için kullanılır. Sabit kaynak seti olacaktır. Bir iş parçacığının aynı sahip olduğu her seferinde kaynak sayısı azalır. Semafor sayısı 0'a ulaştığında, başka hiçbir iş parçacığının kaynağı almasına izin verilmez. İş parçacıkları, kaynak sürümüne sahip diğer iş parçacıkları kadar engellenir.
Kısacası, temel fark, kaynağı aynı anda almak için kaç iş parçacığına izin verildiğidir?
Bir kaynağa seri erişim için bir muteks kullanılırken, semafor bir kaynağa erişimi belirli bir sayıya kadar sınırlar. Bir muteksi, erişim sayısı 1 olan bir semafor olarak düşünebilirsiniz. Semafor sayınızı neye ayarlarsanız ayarlayın, bu evreler kaynak engellenmeden önce kaynağa erişebilir.
Bir semafor, bir sayma senkronizasyon mekanizmasıdır, muteks değildir.
Bu sorunun ilgili cevapları ve resmi Java kılavuzuna bağlantısı vardır : Java'da Mutex var mı?
Semafor :
Sayma semaforu. Kavramsal olarak, bir semafor bir dizi izni korur.
acquire()
Bir izin mevcut olana kadar gerekirse her blok ve sonra onu alır. Her birirelease()
bir izin ekler ve potansiyel olarak bir engelleyici edineni serbest bırakır. Ancak, gerçek izin nesneleri kullanılmaz; Semafor sadece mevcut sayıyı tutar ve buna göre hareket eder.
Semaforlar genellikle bazı (fiziksel veya mantıksal) kaynaklara erişebilen iş parçacığı sayısını kısıtlamak için kullanılır.
Java'da yerleşik Mutex API yoktur. Ancak ikili semafor olarak uygulanabilir.
Birine başlatılan ve en fazla bir izne sahip olacak şekilde kullanılan bir semafor, karşılıklı bir dışlama kilidi işlevi görebilir. Bu daha yaygın olarak ikili semafor olarak bilinir, çünkü yalnızca iki durumu vardır: bir izin kullanılabilir veya sıfır izin kullanılabilir.
Bu şekilde kullanıldığında, ikili semafor, (birçok Kilit uygulamasından farklı olarak) özelliğe sahiptir , "kilit", sahibinden başka bir evre tarafından serbest bırakılabilir (semaforların sahiplik kavramı olmadığından) . Bu, kilitlenme kurtarma gibi bazı özel bağlamlarda yararlı olabilir.
Yani Semafor ve Mutex arasındaki temel farklar :
Semafor, bir kaynağa erişim izinleri için iş parçacığı sayısını kısıtlar. Mutex, yalnızca bir iş parçacığının kaynağa erişmesine izin verir.
Hiçbir iş parçacığı Semafor'a sahip değil. Konular, arama acquire()
ve release()
yöntemlerle izin sayısını güncelleyebilir . Mutekslerin kilidi yalnızca kilidi tutan ip ile açılmalıdır.
Koşul değişkenleriyle bir muteks kullanıldığında, ima edilen bir parantez vardır — programın hangi kısmının korunduğu açıktır . Eşzamanlı programlamaya gitme olarak adlandırılabilecek bir semafor için bu zorunlu değildir - güçlüdür ancak yapılandırılmamış, belirsiz bir şekilde kullanımı çok kolaydır.
Mutex, ikili semafordur. İlk Gelen İlk Hizmet prensibinin karşılanması için 1 ile başlatılmalıdır. Bu, her muteksin diğer özel mülkiyet için bize getiriyor: yapanın aşağı , does biri olmalıdır yukarı . Ergo, bazı kaynaklar üzerinde karşılıklı dışlanma elde ettik.
Şimdi bir muteksin özel bir genel semafor durumu olduğunu görebilirsiniz.
Semafor senkronizasyon nesnesiklasik bir trafik ışığı uygular. Trafik ışığı, sayaç tarafından paylaşılan bir kaynağa erişimi kontrol eder. Sayaç sıfırdan büyükse, erişim izni verilir; Sıfır ise erişim reddedilir. Sayaç, paylaşılan kaynağa erişime izin veren izinleri sayar. Daha sonra kaynağa erişmek için bir iş parçacığının trafik ışığından izin alması gerekir. Genel olarak, bir trafik ışığı kullanmak için, paylaşılan kaynağa erişmek isteyen iş parçacığı bir izin almaya çalışır. Trafik ışığı sayısı sıfırdan büyükse, iş parçacığı bir izin alır ve trafik ışığı sayısı azaltılır. Aksi takdirde, iş parçacığı bir izin alana kadar kilitlenir. İş parçacığının artık paylaşılan kaynağa erişmesi gerekmediğinde, izni serbest bırakır, böylece trafik ışığı sayısı artar. İzin bekleyen başka bir konu varsa, o sırada bir izin alır. Java'nın Semafor sınıfı bu mekanizmayı uygular.
Semaphore'un iki kurucusu vardır:
Semaphore(int num)
Semaphore(int num, boolean come)
num , iznin ilk sayısını belirtir. Num, belirli bir zamanda paylaşılan bir kaynağa erişebilen iş parçacığı sayısını belirtir. Num bir ise, kaynağa her seferinde bir iş parçacığı erişebilir. Ayarı ile gelip gerçek gibi, sen bekliyorsun ipler onlar istenen sırayla izin verilir garanti edemez.
Eşsiz olanı karşılaştırırsınız, teknik olarak bir Semafor ile muteks arasında hiçbir fark yoktur, bu mantıklı değil. Mutex, uygulama mantığınızdaki herhangi bir isim gibi sadece önemli bir isimdir, "1" de bir semaforu başlattığınız anlamına gelir, genellikle karşılıklı dışlamayı sağlamak için bir kaynağı veya korumalı bir değişkeni korumak için kullanılır.