2011-06-22 10 views
8

traté de sincronizar en un objeto en mi código de abajo:NullPointerException en la cuenta sincronizada

public void myMethod() { 
    synchronized (globalObj) { 
     //Do something here 
    } 
} 

El código se ejecuta en un hilo. El problema es que, otro hilo puede establecer 'globalObj' en nulo. Entonces, 'synchronized (globalObj)' lanzará NullPointerxception cuando 'globalObj' se haya establecido en nulo por otros hilos.

¿Cuál es la mejor práctica para sincronizar en un objeto, por lo que NullPointerException no se lanzará?

Gracias.

+0

Más código, por favor. –

Respuesta

25

No debe estar sincronizando en una referencia que puede ser modificada. Si se permite otro subproceso para reemplazar globalObj, eso significa que puede mantener un bloqueo en el antiguo globalObj, mientras que otro subproceso funciona en uno completamente diferente: el bloqueo no le ayuda en absoluto.

Lo que debe hacer en su lugar es tener una separada Object para este propósito:

static final Object lockObj = new Object(); 

public void myMethod() { 
    synchronized (lockObj) { 
    // do something with globalObj here 
    } 
} 

Desde lockObj nunca cambia, siempre vas a utilizar la misma cerradura - no hay problemas.

1

Asegúrese de que sincronice en un objeto que no puede ser nulo ...

Por qué están estableciendo que la globalObj en nulo? ¿Cuál debería ser la semántica de concurrencia para esto? ¿Es por accidente?

Si la necesidad de bloquear desaparece a veces (parece extraño, sin embargo), puede agregar una verificación nula (por supuesto, tendría que sincronizar en otra cosa para evitar una condición de carrera de la primera comprobación de nulo, y luego tenerlo configurado para anular inmediatamente después).

Por favor, describa su situación con más detalle.

0

Cree un miembro de clase de objeto privado que no tenga ningún establecedor público y asegúrelo.

6

No se puede sincronizar en una referencia null. La mejor práctica es sincronizar en un objeto final (para garantizar que nunca sea null), o (mejor aún) usar las abstracciones de concurrencia de mayor nivel en los paquetes java.util.concurrent.

Cuestiones relacionadas