5

Sistemin belirli bölümlerinin başlattığı bazı bölümleri bildiren bir boole sahibi olmak istiyorum.eşzamanlı nesne notifyAll() öğesinden önce kilitlenmedi()

Bazı garip nedenlerden dolayı java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll() numaralı hatayı alıyorum.

Garip olan şey, notifyAll() öğesinin, notifyAll() açıkladığım nesne üzerinde denetimi ele geçiren senkronize bir blokta olmasıdır.

Sınıfım böyle başlıyor: Ben bir android uygulaması üzerinde çalışıyorum

public class MyService { 

    public static Boolean notifier = Boolean.valueOf(false); 

    @Override 
    public void start() { 
     synchronized (MyService.notifier) { 
      MyService.notifier = Boolean.valueOf(true); 
      MyService.notifier.notifyAll(); 
     } 
    } 

    @Override 
    public void stop() { 
     synchronized (MyService.notifier) { 
      MyService.notifier = Boolean.valueOf(false); 
      MyService.notifier.notifyAll(); 
     } 
    } 
    ... 
} 

. Herhangi bir şeyi etkilemesi gerektiğini düşünmüyorum, ama bu soruya java'nın çalışma şeklini etkilemesi durumunda soruyu tamamlıyorum.

Nesne senkronize bir blok içinde kilitliyse neden istisna oluyor?

+1

[Bu SO Soru] 'na bakabilirsiniz (http://stackoverflow.com/questions/260337/why-does-synchronized-notifyall-result-in-a-illegalmonitorstateexception?rq=1) –

+3

Monitöre ait olduğu için _field_'e değil, _object_. "Boolean.FALSE" ile senkronizasyon yapıyorsunuz, ancak Boolean.TRUE değerini bildiriyorsunuz (veya tersi). –

+4

Hikayenin ahlakı; Değişken bir nesneyi kilitlemeyin, 'son' olduğundan emin olun. Kodunuz olması gerekenden daha karmaşıktır ama bunun için ne beklediğinizi görmeden bunun yerine ne yazacağınızı öneremem. (her şeyi silebileceğiniz gibi) Bir ExecutorService kullanmak zorunda olduğunuzdan şüpheleniyorum. –

cevap

17

nesne üzerinden

MyService.notifier = Boolean.valueOf(true); 

takasları üzerinde kilitleme olduğunuz satır, yeni bir nesneye bir referansla değişken değiştirir. Bu nedenle, bloğa girdiğinizde kilidi aldığınız nesne, notifyAll'u çağırdığınız ile aynı değildir. Tüm notifyAll, senkronize blok girildikten sonra yaratılan yeni nesne olan çağrılan nesnenin kilidini almamış olduğunu bilir.

Tüm iş parçacıkları aynı kilidi kullanmalıdır. Ian Roberts'ın dediği gibi, kilit nesneye aittir. Nesnenin üzerine yazarsanız, yeni bir kilitiniz vardır.

+0

Teşekkürler. Bununla takıldım. –

+1

@ J-Rou: Yardım etmekten mutluluk duyuyorum. Herkes bir süre içinde sıkışır, bu bir mesleki tehlike. –