3.1 Aktif nesne
Etkin nesne, bir yöntemin yürütme iş parçacığını çağrıldığı iş parçacığından ayıran bir tasarım desenidir. Bu kalıbın amacı, eşzamansız yöntem çağrıları ve bir istek işleme zamanlayıcısı kullanarak paralel yürütme sağlamaktır.
Basitleştirilmiş sürüm:
Klasik varyant:
Bu şablonun altı öğesi vardır:
- İstemcinin genel yöntemlerine bir arabirim sağlayan bir proxy nesnesi.
- Etkin nesne için erişim yöntemlerini tanımlayan bir arabirim.
- İstemcilerden gelen isteklerin listesi.
- Sorguların yürütülme sırasını belirleyen bir zamanlayıcı.
- Etkin nesne yöntemlerinin uygulanması.
- İstemcinin bir sonuç alması için bir geri arama prosedürü veya değişken.
3.2 kilit
Kilit modeli, birden çok iş parçacığı arasında paylaşılan bir kaynağa özel erişim sağlayan bir eşitleme mekanizmasıdır. Kilitler, eşzamanlılık denetimi ilkesini zorlamanın bir yoludur.
Temel olarak, her iş parçacığının ilgili paylaşılan kaynağa erişmeden önce "kilidi almaya" çalıştığı varsayımıyla bir yazılım kilidi kullanılır.
Bununla birlikte, bazı sistemler, kilitli bir kaynağa yetkisiz erişim girişiminin, erişim sağlamaya çalışan iş parçacığına bir istisna atılarak durdurulacağı zorunlu bir kilitleme mekanizması sağlar.
Semafor , en basit kilit türüdür. Veri erişimi açısından, erişim modları arasında herhangi bir ayrım yapılmaz: paylaşılan (salt okunur) veya özel (okuma-yazma). Paylaşılan modda, birden fazla iş parçacığı salt okunur modda verilere erişmek için bir kilit isteyebilir. Özel erişim modu, güncelleme ve silme algoritmalarında da kullanılır.
Kilit türleri, iş parçacığının yürütülmesinin devam etmesini engelleme stratejisi ile ayırt edilir. Çoğu uygulamada, bir kilit talebi, iş parçacığının kilitli kaynak kullanılabilir olana kadar yürütmeye devam etmesini engeller.
Spinlock, erişim verilene kadar bir döngüde bekleyen bir kilittir. Bu tür bir kilit, bir iş parçacığı bir kilit için az bir süre beklerse çok verimli olur, böylece iş parçacıklarının aşırı yeniden programlanması önlenir. Erişim için beklemenin maliyeti, iş parçacıklarından biri kilidi uzun süre tutarsa önemli olacaktır.
Kilitleme mekanizmasını etkili bir şekilde uygulamak için donanım düzeyinde destek gereklidir. Donanım desteği, "test et ve ayarla", "getir ve ekle" veya "karşılaştır ve değiştir" gibi bir veya daha fazla atomik işlem olarak uygulanabilir. Bu tür talimatlar, kilidin ücretsiz olup olmadığını kesintisiz olarak kontrol etmenize ve öyleyse kilidi almanıza olanak tanır.
3.3 Monitör
İzleme modeli, paylaşılan kaynaklara erişim sağlayan üst düzey bir işlem etkileşimi ve eşitleme mekanizmasıdır. Genellikle donanım veya bir dizi değişken olmak üzere ortak bir kaynak kullanarak iki veya daha fazla bilgisayar görevini senkronize etmeye yönelik bir yaklaşım.
Monitör tabanlı çoklu görevde, derleyici veya yorumlayıcı, programcıya şeffaf bir şekilde uygun biçimde biçimlendirilmiş rutinlere kilit açma kodunu şeffaf bir şekilde ekler ve programcıyı açıkça senkronizasyon ilkellerini çağırmaktan kurtarır.
Monitör şunlardan oluşur:
- paylaşılan bir kaynakla etkileşime giren bir dizi prosedür
- muteks
- bu kaynakla ilişkili değişkenler
- bir yarış koşulundan kaçınmak için koşulları tanımlayan bir değişmez
İzleme prosedürü muteksi çalışmaya başlamadan önce alır ve prosedürden çıkılana kadar veya belirli bir koşul beklenene kadar tutar. Her prosedür, muteksi serbest bırakmadan önce değişmezin doğru olduğunu garanti ederse, o zaman hiçbir görev, bir yarış durumunda kaynağı elde edemez.
Java'da eşitlenmişwait()
işleç ve yöntemleriyle bu şekilde çalışır notify()
.
3.4 Çift kontrol kilitleme
Çift kontrollü kilitleme , bir kilit elde etme yükünü azaltmayı amaçlayan paralel bir tasarım modelidir.
İlk olarak, herhangi bir senkronizasyon olmadan engelleme durumu kontrol edilir. Bir iş parçacığı, yalnızca denetimin sonucu kilidi alması gerektiğini gösteriyorsa bir kilit almaya çalışır.
//Double-Checked Locking
public final class Singleton {
private static Singleton instance; //Don't forget volatile modifier
public static Singleton getInstance() {
if (instance == null) { //Read
synchronized (Singleton.class) { //
if (instance == null) { //Read Write
instance = new Singleton(); //
}
}
}
}
İş parçacığı güvenli bir ortamda tekil bir nesne nasıl oluşturulur?
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
}
Farklı iş parçacıklarından bir Singleton nesnesi oluşturursanız, aynı anda birkaç nesnenin oluşturulduğu bir durum olabilir ve bu kabul edilemez. Bu nedenle, nesne oluşturma işlemini senkronize edilmiş bir ifadeye sarmak mantıklıdır.
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
Bu yaklaşım işe yarayacak, ancak küçük bir dezavantajı var. Nesne oluşturulduktan sonra, gelecekte onu her almaya çalıştığınızda, senkronize blokta bir kontrol yapılacaktır, bu da mevcut iş parçacığının ve onunla bağlantılı her şeyin kilitleneceği anlamına gelir. Yani bu kod biraz optimize edilebilir:
public static Singleton getInstance() {
if (instance != null)
return instance;
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
Bazı dillerde ve/veya bazı makinelerde bu kalıbı güvenli bir şekilde uygulamak mümkün değildir. Bu nedenle, bazen bir anti-desen olarak adlandırılır. Bu tür özellikler, Java Bellek Modeli ve C++ Bellek Modeli'nde "önce olur" katı sıra ilişkisinin ortaya çıkmasına neden olmuştur.
Tipik olarak, Singleton tasarım deseni gibi çok iş parçacıklı programlarda yavaş başlatma uygulama yükünü azaltmak için kullanılır. Bir değişkenin tembel başlatılmasında, hesaplamada değişkenin değeri gerekli olana kadar başlatma ertelenir.
3.5 Zamanlayıcı
Zamanlayıcı, bir çizelgeleme ilkesini uygulamak için bir mekanizma sağlayan, ancak belirli bir ilkeden bağımsız olan paralel bir tasarım modelidir. Bekleyen iş parçacıklarının sırasını açıkça belirten bir nesne kullanarak iş parçacıklarının sıralı kodu yürütmesi gereken sırayı kontrol eder.
GO TO FULL VERSION