2011-07-21 16 views
8

He escrito el siguiente código:ScheduledThreadPoolExecutor, cómo dejar de JAVA clase ejecutable

import java.util.Calendar; 
import java.util.concurrent.ScheduledThreadPoolExecutor; 
import java.util.concurrent.TimeUnit; 

class Voter { 
public static void main(String[] args) { 
    ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2); 
    stpe.scheduleAtFixedRate(new Shoot(), 0, 1, TimeUnit.SECONDS); 
} 
} 

class Shoot implements Runnable { 
Calendar deadline; 
long endTime,currentTime; 

public Shoot() { 
    deadline = Calendar.getInstance(); 
    deadline.set(2011,6,21,12,18,00); 
    endTime = deadline.getTime().getTime(); 
} 

public void work() { 
    currentTime = System.currentTimeMillis(); 

    if (currentTime >= endTime) { 
     System.out.println("Got it!"); 
     func(); 
    } 
} 

public void run() { 
    work(); 
} 

public void func() { 
    // function called when time matches 
} 
} 

quisiera detener el ScheduledThreadPoolExecutor cuando la func() se llama. ¡No hay necesidad de que funcione más! Creo que debería poner la función func() dentro de la clase Votante, y luego crear algún tipo de devolución de llamada. Pero tal vez puedo hacerlo desde dentro de la clase Shoot.

¿Cómo puedo resolverlo correctamente?

+0

No estoy muy familiarizado con 'ScheduledThreadPoolExecutor', pero mi primera conjetura sería' stpe.shutdown() '. Necesitas hacer que 'stpe' sea accesible desde' func() 'para eso. Puede ser razonable comenzar un segundo hilo (¿programado?) Que se ejecuta en el tiempo límite y llama a la función 'shutdown()'. – Dorus

Respuesta

20

El ScheduledThreadPoolExecutor le permite ejecutar su tarea de inmediato o programarla para que se ejecute más tarde (también puede establecer ejecuciones periódicas).

Por lo tanto, si va a utilizar esta clase para detener su ejecución de la tarea tenga en cuenta esto:

  1. No hay manera de garantizar que un hilo se detendrá su ejecución. Compruebe la documentación Thread.interrupt().
  2. El método ScheduledThreadPoolExecutor.shutdown() configurará como cancelada su tarea, y no intentará interrumpir sus hilos. Con este método, realmente evita la ejecución de tareas más nuevas y la ejecución de tareas programadas pero no iniciadas.
  3. El método ScheduledThreadPoolExecutor.shutdownNow() interrumpirá los hilos, pero como dije en el primer punto de esta lista ...

Cuando desee detener el planificador que hay que hacer algo como esto:

//Cancel scheduled but not started task, and avoid new ones 
    myScheduler.shutdown(); 

    //Wait for the running tasks 
    myScheduler.awaitTermination(30, TimeUnit.SECONDS); 

    //Interrupt the threads and shutdown the scheduler 
    myScheduler.shutdownNow(); 

¿Pero y si necesita detener solo una tarea?

El método ScheduledThreadPoolExecutor.schedule(...) devuelve ScheduleFuture que es una representación de su tarea ya programada. Por lo tanto, puede llamar al método ScheduleFuture.cancel(boolean mayInterruptIfRunning) para cancelar su tarea e intentar interrumpirla si es necesario.

+5

Necesito solo una aclaración sobre lo anterior: ¿Por qué no podemos simplemente hacer myScheduler.shutdownNow()? Lo que me preocupa es la finalización de una tarea para completar puede tomar cualquier tiempo arbitrario. Entonces, ¿por qué ir por las dos primeras líneas? – abksrv

Cuestiones relacionadas