2013-08-13 16 views
5

İki iş parçacığı tasarlıyorum: biri oyuncuların adını almalı ve ikinci iş parçacığı devam etmek için ayarlanan ismin beklemesini beklemek zorundadır, ancak ilk iş parçacığındaki tüm öğeyi() bildirmeniz gerekir. IllegalMonitorStateException hatasını atıyor.notifyAll() ekleri IllegalMonitorStateException

private NameFecth nameFetch; 
private UseName useName; 
private Object nameSetLock; 
public static void method{ 
    nameSetLock = new Object() 
    nameFetch = new NameFetch(nameSetLock); 
    useName = new UseName(nameSetLock); 
    Thread nameFetchThread = new Thread(nameFetch); 
    nameFetchThread.start(); 
    Thread useNameThread = new Thread(useName); 
    useNameThread.start(); 
} 

public class NameFetch implements Runnable{ 
    /*variables and constructers*/ 

    public void run(){ 
     /*get name and set the variable somehow*/ 
     synchronized(nameSetLock){ 
     notifyAll(); 
     } 
    } 
} 

public class UseName implements Runnable{ 
    /*variables and constructers*/ 

    public void run(){ 
    while(!nameBeenSet){ 
     synchronized(nameSetLock){ 
     try{ 
      wait(); 
     }catch(InterruptedException e) {} 
     } 
    } 

} 

Neyi yanlış yaptım?

+0

Bu tam bir koddur? – saurav

cevap

13

Object.notifyAll belgelendiği gibi sen bekleyen veya bildiren ediyoruz şeye senkronize etmeden wait ve notify aradığınız:

Atmalar:
IllegalMonitorStateException - .kontrol Şu anki iş parçacığı bu nesnenin monitörünün sahibi değil.

Yani bu:

synchronized(nameSetLock){ 
    notifyAll(); 
} 

olmalıdır: wait için

synchronized(nameSetLock){ 
    nameSetLock.notifyAll(); 
} 

... ve aynen. Geçerli kodunuzun synchronized yerine syncronized kullanıyor olsanız bile derlenmeyeceğini unutmayın; bu, gerçek kodunuzu göndermediğinizi gösterir. Kodu yazarken aslında sorununu değiştirmiş olabilirsiniz - bu durumda sorunuzu daha fazla temsilci olarak düzenlemelisiniz. O nesne kilidi kalmadan bekleme() ve notifyAll() çağırmak için çalışıyoruz IllegalStateException

Thrown to indicate that a thread has attempted to wait on an object's 
    monitor or to notify other threads waiting on an object's monitor 
    without owning the specified monitor. 

ait JavaDoc'u itibaren

+0

düzenlenmiş, teşekkürler. Belgeyi okudum, ama ne anlama geldiğini bilmiyorum, eşzamanlılık için gerçekten yeni. Teşekkürler – Newyo

1

Sorununuz, kilitle hatalı olarak kullandığınız gibi görünüyor. Sen senkronize blok nameSetLock kullanılıyorsa ve senkronize bir (bu sayme) (ki ise NameFetch nesne örneği üzerinde notifyall çağırıyorlar.

kilidi ve nameSetLock.notifyAll kullanmak istediğinizde nameSetLock.wait yapmalıyım

.. bildirmek için

+0

useSetLock.wait() yöntemini useName içinde çağırırsam, useName durmasına neden olur mu? – Newyo

+0

Ne olacağı, "kilit" olarak isminin kilitlendiği senkronize edilmiş bloğa bastığınızda, jvm başka bir bloğun, namesetlock kullanılarak kesişen senkronize olup olmadığını kontrol edecektir. Başka bir iş parçacığı bunu kullanıyorsa, senkronize edilmiş bloğu tamamlayarak veya nameSetLock.wait çağırarak denetimini bırakarak diğer senkronize edilmiş blok yayınlanana kadar beklemeye devam eder. –

1

.

Lütfen @Jon'un işe yarayacağını önerdiğini deneyin.

0

Yöntem çağrısında eşitlenmiş eklemeyi unuttuğumda bu bana oluyor.

İlgili konular