2010-11-23 47 views
18

En el código, el temporizador variable especificaría la duración después de la cual finalizará el ciclo while, 60 segundos, por ejemplo.¿Cómo detener la ejecución después de un cierto tiempo en Java?

while(timer) { 
    //run 
    //terminate after 60 sec 
    } 
+1

Parece que estamos refrito de un viejo hilo aquí: http://stackoverflow.com/questions/2550536/java-loop-for-a-certain-duration – Dmitri

+0

Compruebe este artículo: http: // www. yegor256.com/2014/06/20/limit-method-execution-time.html – yegor256

+0

Posible duplicado de [Cómo agotar el tiempo de espera de un hilo] (http://stackoverflow.com/questions/2275443/how-to-timeout-a -thread) – vhunsicker

Respuesta

38
long start = System.currentTimeMillis(); 
long end = start + 60*1000; // 60 seconds * 1000 ms/sec 
while (System.currentTimeMillis() < end) 
{ 
    // run 
} 
+8

pero si una iteración del bucle comienza cuando comienza en 59 segundos y cada iteración del bucle dura más de 1 segundo, pasaría más de 60 segundos ¿no? Es esto lo mejor que se puede hacer. Estoy pidiendo por pura ignorancia. – Ramy

+0

@Ramy: no. El 'start' y' end' son tiempos absolutos, medidos en milisegundos desde la época (medianoche, 1 de enero de 1970 UTC). No hay rollover. –

+6

bien, pero el control solo ocurre al comienzo del ciclo. Entonces, si al comienzo del ciclo, digamos que han pasado 59 segundos, y cada iteración del ciclo toma, digamos, 5 segundos. La próxima vez que se marque el ciclo while, se verificará la condición, habrán transcurrido 64 segundos. Bien, ¿o me estoy perdiendo algo? – Ramy

1

depende de lo que el bucle while está haciendo. Si existe la posibilidad de que se bloquee durante un período prolongado, use TimerTask para programar una tarea y establecer stopExecution, y también .interrupt() su hilo.

Con solo una condición de tiempo en el ciclo, podría permanecer allí esperando por siempre la entrada o un bloqueo (y de nuevo, puede que no sea un problema para usted).

3

Si no puede exceder su límite de tiempo (es un límite difícil), entonces un hilo es su mejor opción. Puede usar un ciclo para terminar el hilo una vez que llegue al umbral de tiempo. Lo que esté sucediendo en ese hilo en ese momento puede interrumpirse, permitiendo que los cálculos se detengan casi al instante. Aquí hay un ejemplo:

Thread t = new Thread(myRunnable); // myRunnable does your calculations 

long startTime = System.currentTimeMillis(); 
long endTime = startTime + 60000L; 

t.start(); // Kick off calculations 

while (System.currentTimeMillis() < endTime) { 
    // Still within time theshold, wait a little longer 
    try { 
     Thread.sleep(500L); // Sleep 1/2 second 
    } catch (InterruptedException e) { 
     // Someone woke us up during sleep, that's OK 
    } 
} 

t.interrupt(); // Tell the thread to stop 
t.join();  // Wait for the thread to cleanup and finish 

Eso le dará una resolución de aproximadamente 1/2 segundo. Al sondear con más frecuencia en el ciclo while, puede obtenerlo. plazo

Su del ejecutable sería algo como esto:

public void run() { 
    while (true) { 
     try { 
      // Long running work 
      calculateMassOfUniverse(); 
     } catch (InterruptedException e) { 
      // We were signaled, clean things up 
      cleanupStuff(); 
      break;   // Leave the loop, thread will exit 
    } 
} 

Actualización basada en la respuesta de Dimitri

Dmitri señaló TimerTask, lo que permitiría a evitar el bucle. Podrías simplemente hacer la llamada de unión y el TimerTask que configuraste se encargaría de interrumpir el hilo. Esto le permitiría obtener una resolución más exacta sin tener que sondear en un bucle.

+0

No es así como '.interrupt()' funciona. A menos que el hilo esté bloqueado, simplemente establece el indicador "interrumpido", el hilo aún debe verificarlo para detener la ejecución. Además, 'InterruptedException' es una excepción comprobada, no puede simplemente arrojarla alrededor de un código arbitrario (su ejemplo no se compilará). – Dmitri

17

debe probar los nuevos servicios de Java Executor. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

Con esto no es necesario que programe el ciclo la medición del tiempo por usted mismo.

public class Starter { 

    public static void main(final String[] args) { 
     final ExecutorService service = Executors.newSingleThreadExecutor(); 

     try { 
      final Future<Object> f = service.submit(() -> { 
       // Do you long running calculation here 
       Thread.sleep(1337); // Simulate some delay 
       return "42"; 
      }); 

      System.out.println(f.get(1, TimeUnit.SECONDS)); 
     } catch (final TimeoutException e) { 
      System.err.println("Calculation took to long"); 
     } catch (final Exception e) { 
      throw new RuntimeException(e); 
     } finally { 
      service.shutdown(); 
     } 
    } 
} 
+0

¿cuál es el valor del tiempo de espera establecido aquí? – nikk

+0

¿Qué quiere decir con "tiempo de espera"? El 'Thread.sleep (1337);'? – Murmel

+0

Creo que por "tiempo de espera", @nikk significa la cantidad de tiempo después del cual se cerrará el servicio. – lostsoul29

Cuestiones relacionadas