2010-11-19 9 views
5

veo esto:¿Está bien? Sincronizada (rosca), luego pase = null en el bloque sincronía

// thread is a member of this class 

synchronized(this.thread) 
{ 
    this.thread.running = false; 
    this.thread.notifyAll(); // Wake up anything that was .waiting() on 
    // the thread 
    this.thread = null; // kill this thread reference. 
    // can you do that in a synchronized block? 
} 

¿Está bien para establecer el thread=null si bien mantienen un bloqueo en ella?

Encontré este nugget en un poco de código BB.

+1

¿Hay alguna razón por la que no esté utilizando Thread.interrupt() ya que esto es compatible con las bibliotecas subyacentes? –

Respuesta

7

Sí, está bien. La instrucción sincronizada tomará una copia de la referencia en la que se está bloqueando y utilizará la copia para determinar qué desbloquear al final.

Section 14.19 de la especificación del lenguaje Java no es realmente claro acerca de esto, pero lo hace estado que la expresión se evalúa en el inicio - y no menciona la evaluación de nuevo más adelante.

+0

Está bien, pero es cuestionable si establecer una referencia de subproceso como nulo es una buena idea. – Adamski

+1

@Adamski: Tiendo a tener una opinión razonablemente sólida sobre lo que sincronizo en primer lugar para ser honesto - Pensé que evitaría entrar en eso :) –

+0

De acuerdo - De hecho, IntelliJ me advierte en esta situación sobre la sincronización en una variable no final. – Adamski

3

Hay una diferencia:

synchronized(this.thread) 

está sincronizando en el objeto del campo this.thread puntos a

this.thread = null; 

Usted está reasignando el campo. No está haciendo nada con el objeto al que hizo referencia anteriormente, por lo que el bloqueo sigue siendo válido.

0

Puede hacerlo, pero es casi seguro que el código sea incorrecto para lo que sea que intente lograr. Publique todo el código, y le garantizo que obviamente el programador no entiende la concurrencia.

No reasigne una variable que se utiliza para la sincronización.

0

Solo tiene un problema si también tiene un bloque que le asigna un nuevo valor al hilo. En ese caso, tiene una condición de carrera ya que los dos bloques no se bloquean en el mismo objeto, pero actualizará el mismo campo y será aleatorio en cuanto a qué bloque asigna el último valor.

1

La expresión sincronizada se desreferencia en la entrada, por lo que los usuarios posteriores de este bloqueo obtendrán una NullPointerException. Puede solucionarlo colocando un cheque nulo antes del bloque sincronizado, pero luego ha introducido una condición de carrera.

+0

'Evaluado' en la entrada. – EJP

+3

@EJP más que evaluado: una expresión que se evalúa como nula no causa una NullPointerException. –

Cuestiones relacionadas