2011-04-11 5 views
7

Siempre que comienzo mi hilo siempre hago esta comprobación. No he encontrado en cualquier lugar que llamé inicio en la rosca sin hacer el cheque a continuaciónJava Threading Error IllegalThreadState thread already started

if (!myThread.isAlive()) 
    myThread.start(); 

Sin embargo, termino con IllegalThreadStateException: hilo ya comenzó. Esto realmente bloquea mi aplicación (Android). Entonces, ¿hay algún otro control que deba hacer antes de iniciar un hilo?

+3

El subproceso puede no estar activo y todavía iniciado: es decir, puede haberse iniciado anteriormente y ya ha finalizado. Tal vez ese es el caso aquí? – pajton

+0

Si dos hilos comparten una referencia a myThread, entonces ambos pueden examinar myThread.isAlive() y ambos ven falso, luego ambos intentan comenzar. Probablemente no deberías iniciar hilos como este (pasando alrededor de un objeto Thread que luego comienzas). Probablemente deberías estar usando un ExecutorService de java.util.concurrent.Executors. Si publica más detalles sobre lo que están haciendo los hilos, entonces puedo dar consejos más específicos. –

Respuesta

3

¿Creas una nueva instancia para myThread reference using new? Solo puede realizar myThread.start() una vez en una sola instancia.

Comprobar si está vivo no es el camino correcto. Crea una nueva instancia.

11

Debería comprobar si el hilo ya ha comenzado a usar getState() e iniciarlo solo si es state is NEW; de lo contrario, cree un hilo nuevo (si es necesario).

+2

permítanme aclarar este enfoque. if (thread.getState() == Thead.State.NEW) – Androider

+0

then thread.start() – Androider

+0

Entonces, si hay algún otro estado, ¿creas un nuevo hilo? – Androider

0

Acabo de tener un caso similar aquí, es por eso que doy una respuesta tardía.

El problema es que su solución con Thread.isAlive() y Thread.start() no es multihilo. Puede suceder que un primer hilo invoque su código, ejecute isAlive() y en algún lugar dentro de Thread.start(), después de que se inició el nuevo subproceso y antes de que se cambie de estado, se produce un cambio de tarea y un segundo llamador ejecuta isAlive() cuando todavía está false llamando start(). dos veces. Para empeorar las cosas en algún lugar dentro de start() parece que se fuerza un cambio de tarea y, por lo tanto, este problema aparece con bastante frecuencia.

Solución: Reemplazar start() para que sea multi-hilo de seguridad, por ejemplo

private final AtomicBoolean started = new AtomicBoolean(false); 
/* (non-Javadoc) 
* @see java.lang.Thread#start() 
*/ 
@Override 
public synchronized void start() { 
    if (!started.getAndSet(true)) { 
     super.start(); 
    } 
} 

Entonces el problema no aparecerá más, incluso si start() accidentalmente se llama dos veces.