2012-05-16 17 views
6

Pero me estoy sincronizando en el objeto 'roster' en todos los sitios donde se actualiza. Cómo ?java.lang.IllegalMonitorStateException: objeto no bloqueado por subproceso antes de wait()

El código erróneo:

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

¿Qué hace reload() hacer? – Affe

+0

donde llamaste notifica – Ronnie

Respuesta

8

Con "recibe new'ed" quiere decir que crea un nuevo objeto lista ?

¿Estás seguro de que estás sincronizando correctamente? La sincronización ocurre en instancias, no en variables. Entonces, si lo hace, p.

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

Entonces sólo sincroniza con la edad , no el nuevo roster.

Así que el siguiente código debe producir el mismo error:

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 no sucede en el nombre de la variable , sino en los contenidos . ¡Si sobrescribe los contenidos, no se vuelve a sincronizar con el nuevo valor!

+0

si tienes razón en esta observación, no veo cómo podría ser la causa de la excepción. Puedes elaborar ? – kellogs

+1

La opción n. ° 1 sería si roster.reload() podría de alguna manera cambiar el objeto al que se refiere la variable de lista. La opción n. ° 2 es que, antes de llegar a la llamada a la espera() o mientras está en ella, algún otro subproceso cambia a lo que se refiere la variable de la lista. En cualquier caso, la Lista en la que sincronizó no será la misma Lista en la que está esperando(). – Sbodd

+0

Ver la respuesta editada. –

Cuestiones relacionadas