2010-06-16 11 views
5

Tengo una clase que amplía la clase Thread y tiene su método de ejecución implementado como tal.android thread management onPause

public void run(){ 
    while(!terminate){ 
     if(paused){ 
      Thread.yield(); 
     }else{ 
      accummulator++; 
     } 
    } 
} 

Este tema se generó a partir del método onCreate.

Cuando mi UI está oculta (cuando se presiona la tecla de inicio) mi método onPause establecerá la marca pausada en verdadero y cederá la banda de rodadura. Sin embargo, en el DDMS todavía veo el uTime del hilo acumulado y su estado como "en ejecución".

Así que mi pregunta es. ¿Cuál es la forma correcta de detener el hilo para que no agote el tiempo de CPU?

Respuesta

4

En realidad, es una mala práctica mantener un hilo ejecutándose después de onPause. La razón es que, después de OnPause, es posible que su aplicación se pierda de memoria en cualquier momento sin que usted lo sepa, por lo tanto, no podrá realizar la limpieza después de usted.

La forma correcta de hacerlo es detener el hilo en Pausa y recrearlo en Reanudar. Si necesita estado, puede usar los métodos o configuraciones saveState integradas de Android o cualquiera que lo conserve.

+0

Sí, esa es la conclusión que se me ocurrió también. Además, creo que el mejor método de implementación no es subclasificar directamente desde Thread, sino usar la interfaz Runnable. De esta forma puede matar el hilo pero aún así tener la capacidad de "reanudarlo" instanciando otro hilo, sin perder el estado. Concedido que onDestroy o la aplicación no se elimina y vuelve a crear. –

0

Su variable paused probablemente se esté almacenando en caché localmente. Esto se debe a que solo se lee y no se modifica en el ciclo. Entonces, lo que está sucediendo es que el compilador/intérprete/jitter optimiza leyendo solo la variable una vez y luego solo ejecutando la rama else. Debe marcar ese campo como volatile para que la variable pause se lea cada iteración a través del ciclo. Consulte la documentation de la palabra clave volatile. Aquí está some info about threading y some info about synchronization and concurrency.

+0

No estoy tan preocupado por los recursos de ocupación variable pausados. Estoy preocupado de que el hilo aún esté en bucle a pesar de que el hilo de la interfaz de usuario se ha detenido. –

+0

He actualizado la respuesta para explicar más claramente lo que está sucediendo. La respuesta no fue sobre la variable de pausa y los recursos. El hilo todavía está en bucle porque la variable pausada no está marcada como volátil y no se vuelve a leer. Esta es solo una de las sutilezas de la programación multiproceso. – Qberticus

1

Aunque estés invocando thread.yield(), estás dentro de un ciclo while() que probablemente esté repitiendo miles de veces por segundo, cada vez que se llame a .yield() pero el hecho de que está saliendo en bucle de control significa que está consumiendo recursos. Si pones un mensaje de Log.d allí, verás lo que quiero decir.

Recomiendo usar un Thread.sleep() en lugar de Thread.yield(). La razón es que, mientras un hilo está durmiendo, se produce. Además, con el modo de reposo obtienes la ventaja adicional de ralentizar el while() y no agotar los recursos. Un intervalo de espera de 500ms debería ser suficiente =)

+0

el subproceso se usará finalmente como un subproceso en un lienzo y se ejecutará lo más rápido posible. Creo que voy a intentar eliminar el hilo y volver a crearlo en el controlador onresume –

+0

. Vale la pena enfatizar que los bucles cerrados como el que está en tu código son CPU hogs. En un dispositivo móvil, un cerdo de la CPU se comerá la batería a toda prisa. –

+0

No he tenido un problema con 'Thread.yield' (también conocido como' Thread.sleep (0) ') y uso elevado del procesador: el programador de hilos tiene una granularidad * mínima * por debajo de *" miles de veces por segundo ". –

Cuestiones relacionadas