Java ile içeride eğer ifadesiyle ikili semafor inşa etmek mümkün değildir Neden

oy
0

Bana biraz karışık yapan küçük bir sorum var.

Bu benim kodudur:

public synchronized void P() {
    while(!_state) {
        this.wait();
    }
    _state = false;
}

Bu yöntem semaforu alarak sorumludur. Neden birlikte ikili semafor inşa etmek mümkün değildir ifdeyimi yerine whiledöngü?

oracle dokümanlar diyor ki:

Birincisi, serpiştirmek için aynı nesne üzerinde senkronize yöntemlerden iki çağrımı için mümkün değildir. bir iplik, bir nesne için senkronize bir yöntemin uygulanması zaman, birinci ipliğin kadar aynı obje bloğu (yürütülmesi askıya) için yöntemler senkronize çağırmak diğer iş nesnesi ile yapılır.

> Yani sadece tek bir iş parçacığı bekleyin üzerinde engellenmesi gerekir () yöntemi - Peki tam yalnızca bir iplik P () yöntemi içinde olmalıdır. İpliklerinin geri kalanı (P) yöntemi düzeyde engellenmesi gerekir. Ama yerine am zaman while()için if()buna düzgün çalışmıyor

Oluştur 20/10/2018 saat 13:58
kaynak kullanıcı
Diğer dillerde...                            


2 cevaplar

oy
0

Neden birlikte ikili semafor inşa etmek mümkün değildir ifdeyimi yerine whiledöngü?

Derin bir cevap için, Oracle'ın aracılığıyla çalışmalıdır Güvenlikli Blokları öğretici .

Kısa cevap nedenlerinden bir çift yok demek _stateolabilir falsezaman wait()çağrı döndürür:

  1. Çoklu tüketiciler: Genellikle ile Uyuyanlar uyanmak için güvenlidir notifyAll()yerine notify()ve iki veya daha çok iş parçacığı diyebiliriz ki bir program yazarsanız P()fonksiyonu, muhtemelen sadece istediğiniz birini bazılarının farklı iplik çağırdığında devam etmesine izin verilmesi için V()işlev . Hepsi "uyanmak" Yani, sadece bir set isteyeceksiniz _state=false;ve başkalarının uyu isteyeceksiniz.

  2. Aynı nesne oluyor notifyAll()birden fazla nedenden dolayı çağrıları. Bu iyi bir uygulama değil, ama özellikle pek çok geliştirici kodun katkı sağlayacak projelerde, olmuyor. Bu durumda, wan yok P()nesne yanlış bir nedenle bildirildi eğer dönmek için çağrı. Bunu geri dönüp Beklemeye devam etmek istiyorum.

  3. Belgeleri o.wait()o nesne bile dönmesine izin söylüyor ohiç haberdar edilmemiştir. Bu olarak bilinir "sahte uyandırma." Nadiren olur ve sadece bazı işletim sistemlerinde, ancak daha etkin bir biçimde uygulanmasını sağlar, çünkü onlar buna izin wait()ve notify().

Cevap 20/10/2018 saat 15:55
kaynak kullanıcı

oy
0

synchronizedyöntem eşdeğerdir synchronized(this)bloke eder.

Sadece 1 iplik senkronize blok girmek için izin verilir. Bunu girerek, iplik aquires kilitleyin. Ne zaman waitsenkronizasyon bloğunun içinde, kilidi (nesne izleme) bırakın ve mevcut iplik park edin. Bu anda, başka bir iş parçacığı bu bloğu girmesine izin verilir. Diğer iplik çağıracağı zaman Yürütme devam edecek notifyya da notifyAllaynı nesne üzerinde waitçağrıldı. Onaylanmış iplik "çıkış bekleme durumu" Verilen senkronizasyon bloğun kilit çıkacak ne zaman.

Özetle - Eğer, bu yürütme engellemez bekliyoruz gibi beklemeye diğer konu senkronizasyon kilidi aquire sağlayan sadece uyumaya iplik bekleyen koyar, çalışmıyor.

Çünkü Yani, ulaşmak istediğiniz şeyi yapamayız waitişin farklı o zaman bekliyoruz. Burada ne kullanmak istediğiniz vardır ReentrantLock. https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

Cevap 20/10/2018 saat 14:12
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more