2010-10-28 11 views
114

Cómo configurar un temporizador, por ejemplo durante 2 minutos, para tratar de conectarse a una base de datos y luego lanzar una excepción si hay algún problema en la conexión?¿Cómo configurar un temporizador en Java?

+1

Coul the OP aclarar si desean intentar la acción por lo menos durante 2 minutos, o si la excepción debe ser lanzada ahora más tarde los dos minutos, incluso si hay un intento de conexión actualmente en curso – thecoshman

Respuesta

224

Así que la primera parte de la respuesta es cómo hacer lo que el sujeto pregunta, ya que así fue como lo interpreté inicialmente y algunas personas parecieron encontrarlo útil. La pregunta fue aclarada desde entonces y he extendido la respuesta para abordar eso.

poner un reloj de

Lo primero que necesita para crear un temporizador (estoy usando la versión java.util aquí):

import java.util.Timer; 

..

Timer timer = new Timer(); 

Para ejecutar el tarea una vez que lo haría:

timer.schedule(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000); 

Para que la repetición de tareas después de la duración puede hacer:

timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000, 2*60*1000); 

Haciendo un tiempo de espera de tarea

Para ver específicamente lo que la pregunta aclarado pregunta, que está tratando de realizar una tarea para una dado un período de tiempo, puede hacer lo siguiente:

ExecutorService service = Executors.newSingleThreadExecutor(); 

try { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      // Database task 
     } 
    }; 

    Future<?> f = service.submit(r); 

    f.get(2, TimeUnit.MINUTES);  // attempt the task for two minutes 
} 
catch (final InterruptedException e) { 
    // The thread was interrupted during sleep, wait or join 
} 
catch (final TimeoutException e) { 
    // Took too long! 
} 
catch (final ExecutionException e) { 
    // An exception from within the Runnable task 
} 
finally { 
    service.shutdown(); 
} 

Esto se ejecutará normalmente con excepciones si la tarea se completa en 2 minutos . Si se ejecuta más tiempo que eso, se lanzará TimeoutException.

Una cuestión es que a pesar de que obtendrá un TimeoutException después de los dos minutos, la tarea de hecho continuará funcionando, aunque presumiblemente una base de datos o una conexión de red con el tiempo y el tiempo de espera lanzar una excepción en el hilo. Pero ten en cuenta que podría consumir recursos hasta que eso suceda.

+0

Oh, supongo que tienes mi problema mal, tengo que tratar repetidamente de conectarme a la base de datos hasta 2 minutos cada vez – Ankita

+1

Actualicé mi respuesta para cubrir la repetición cada 2 minutos – andrewmu

+0

Lo siento pero mi requisito es que quiero dar 2 minutos para conectarme a la base de datos y luego simplemente arrojará un mensaje de error. Es como si quisiera establecer un límite de tiempo para tratar de conectarme a la base de datos. – Ankita

9

Ok, creo que entiendo su problema ahora. Puede usar un futuro para intentar hacer algo y luego esperar un poco si nada ha sucedido.

ej .:

FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() { 
    @Override 
    public Void call() throws Exception { 
    // Do DB stuff 
    return null; 
    } 
}); 

Executor executor = Executors.newSingleThreadScheduledExecutor(); 
executor.execute(task); 

try { 
    task.get(5, TimeUnit.SECONDS); 
} 
catch(Exception ex) { 
    // Handle your exception 
} 
+0

Se lanza una excepción pero el programa no se termina. Por favor, ayúdenme con esto. – Ankita

+2

Puede usar la clase ExecutorService en su lugar de Executor. Tiene el método shutdown() para detener al ejecutor. – Rites

+1

Los ejecutores se tragarán las excepciones lanzadas que no manejas específicamente en tu Callable/Runnable. Si Runnable/Callable no capta y maneja la excepción en sí misma y es proporcionado a usted frente a su propietario, entonces debe subclase el ScheduledExecutorService y anular afterExecute (asegúrese de llamar a super.afterExecute()). El segundo argumento para afterExecute será el throwable de Runnable/Callable – adam

6

Cómo detener el temporizador?Parar y jugar de nuevo cuando hacer algo en este código

timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
    // Your database code here 
    } 
}, 2*60*1000, 2*60*1000); 

Cuando utilizo el timer.cancel();

se detendrá pero si cerca de la forma y abrir de nuevo la excepción es lanzada

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Timer already cancelled. 
    at java.util.Timer.sched(Timer.java:354) 
    at java.util.Timer.scheduleAtFixedRate(Timer.java:296) 
    at View.Electronic_Meeting.this_componentShown(Electronic_Meeting.java:295) 
    at View.Electronic_Meeting.access$000(Electronic_Meeting.java:36) 
    at View.Electronic_Meeting$1.componentShown(Electronic_Meeting.java:85) 
    at java.awt.AWTEventMulticaster.componentShown(AWTEventMulticaster.java:162) 
    at java.awt.Component.processComponentEvent(Component.java:6095) 
    at java.awt.Component.processEvent(Component.java:6043) 
    at java.awt.Container.processEvent(Container.java:2041) 
    at java.awt.Component.dispatchEventImpl(Component.java:4630) 
    at java.awt.Container.dispatchEventImpl(Container.java:2099) 
    at java.awt.Component.dispatchEvent(Component.java:4460) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
17

Uso este

long startTime = System.currentTimeMillis(); 
long elapsedTime = 0L. 

while (elapsedTime < 2*60*1000) { 
    //perform db poll/check 
    elapsedTime = (new Date()).getTime() - startTime; 
} 

//Throw your exception 
+1

hmm ... this funcionaría técnicamente, excepto que no cubre los casos extremos, donde el tiempo se agota ya que está realizando una encuesta DB, w Esto puede ser requerido por el OP – thecoshman

+0

Esta es la única respuesta correcta. Se ejecutará en un solo subproceso y calculará el tiempo de finalización sin deriva. Usar un TimerTask es exactamente lo que no se debe hacer en este caso. Me sorprendió ver cuántos ejemplos en StackOverflow sugieren este mismo tipo de cosas mal dirigidas. – AgilePro

+1

@thecoshman - las implementaciones del temporizador NO interrumpen la operación de DB una vez que está en progreso, ni lo hace. En cualquier caso, solo puede controlar el momento en que inicia la operación de DB. Existe la idea errónea de que necesita un "temporizador" para cronometrar las cosas, pero no es así. Solo necesita HACER algo, y al usar la hora actual, asegúrese de no HACERLO demasiado tiempo. – AgilePro

1
new java.util.Timer().schedule(new TimerTask(){ 
     @Override 
     public void run() { 
      System.out.println("Executed..."); 
      //your code here 
      //1000*5=5000 mlsec. i.e. 5 seconds. u can change accordngly 
     } 
    },1000*5,1000*5); 
+0

solo copie la plaga encima del código, funcionará bien. He dado dos veces "el tiempo" primero es la primera vez para ejecutar este código y el segundo es para el intervalo de tiempo. –

Cuestiones relacionadas