2012-05-16 12 views
6

Ma io sto sincronizzando sull'oggetto 'roster' ovunque venga new'ed. Come mai ?java.lang.IllegalMonitorStateException: oggetto non bloccato da thread before wait()

Il codice incriminato:

public Roster getRoster() { 
    if (roster == null) { 
     return null; 
    } 

    if (!roster.rosterInitialized) { 
     try { 
      synchronized (roster) { 
       roster.reload(); 
       long waitTime = SmackConfiguration.getPacketReplyTimeout(); 
       long start = System.currentTimeMillis(); 
       while (!roster.rosterInitialized) { 
        if (waitTime <= 0) { 
         break; 
        } 
        roster.wait(waitTime); 
        long now = System.currentTimeMillis(); 
        waitTime -= now - start; 
        start = now; 
       } 
      } 
     } 
     catch (InterruptedException ie) { 
      // Ignore. 
     } 
    } 
    return roster; 
} 
+2

cosa fa ricaricare()? – Affe

+0

dove chiami notifica – Ronnie

risposta

8

Con "viene new'ed" si intende la creazione di un nuovo oggetto roster ?

Sei sicuro di essere sincronizzato correttamente? Synchronizsation succede su istanze, non su variabili. Quindi se lo fai, ad es.

synchronized(roster) { 
    roster = new Roster(); 
    // do something 
} 

Poi si sincronizzati solo al vecchio, non il nuovaroster.

Così il seguente codice dovrebbe produrre lo stesso errore:

Roster roster = new Roster(); 
Roster othervariable = roster; 
synchronized(othervariable) { 
    roster = new Roster(); // create a new roster 
    othervariable.wait(1000); // OK, since synchronized with this instance! 
    roster.wait(1000); // NOT OK, not synchronized with *new* roster! 
} 

Synchronizsation non avviene sul nome della variabile, ma sui contenuti . Se si sovrascrivono i contenuti, non si risincronizza con il nuovo valore!

+0

se hai ragione in questa osservazione, non riesco a vedere come potrebbe essere la causa dell'eccezione. Puoi elaborare ? – kellogs

+1

L'opzione 1 sarebbe se roster.reload() potesse in qualche modo modificare l'oggetto a cui si riferisce la variabile roster. l'opzione # 2 è che, prima di arrivare alla chiamata wait() o mentre ci sei dentro, qualche altro thread cambia a cosa si riferisce la variabile del ruolo. In entrambi i casi, il Roster su cui è stato eseguito il sincronismo non sarà lo stesso Roster su cui stai aspettando(). – Sbodd

+0

Vedere la risposta modificata. –

Problemi correlati