una - timer java eclipse
java: ejecutar una función después de un número específico de segundos (10)
Tengo una función específica que quiero que se ejecute después de 5 segundos. ¿Cómo puedo hacer eso en Java?
Encontré javax.swing.timer, pero realmente no puedo entender cómo usarlo. Parece que estoy buscando algo mucho más simple que esta clase.
Por favor agrega un ejemplo de uso simple.
Algo como esto:
// When your program starts up
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// then, when you want to schedule a task
Runnable task = ....
executor.schedule(task, 5, TimeUnit.SECONDS);
// and finally, when your program wants to exit
executor.shutdown();
Hay varios otros métodos de fábrica en Executor
que puede usar en su lugar, si desea más hilos en el grupo.
Y recuerde, es importante apagar al ejecutor cuando haya terminado. El método shutdown()
cerrará limpiamente el grupo de subprocesos cuando se haya completado la última tarea, y se bloqueará hasta que esto suceda. shutdownNow()
terminará el grupo de subprocesos inmediatamente.
Como una variación de la respuesta @tangens: si no puede esperar a que el recolector de basura limpie su hilo, cancele el temporizador al final de su método de ejecución.
Timer t = new java.util.Timer()
t.schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
// close the thread
t.cancel()
}
},
5000
);
Ejemplo de uso de javax.swing.Timer
Timer timer = new Timer(3000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// Code to be executed
}
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!
Este código solo se ejecutará una vez y la ejecución se realizará en 3000 ms (3 segundos).
Como dice Camickr, debe buscar " Cómo usar Swing Timers " para obtener una breve introducción.
Mi código es el siguiente:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here, and if you have to refresh UI put this code:
runOnUiThread(new Runnable() {
public void run() {
//your code
}
});
}
},
5000
);
Su pregunta original menciona el "Temporizador de oscilación". Si de hecho su pregunta está relacionada con SWING, entonces debe usar el Swing Timer y NO el util.Timer.
Lea la sección del tutorial de Swing sobre " Cómo utilizar los temporizadores " para obtener más información.
Todos los demás usuarios requieren para ejecutar su código dentro de un nuevo hilo. En algunos casos de uso simple, es posible que desee esperar un poco y continuar la ejecución dentro del mismo subproceso / flujo.
El código a continuación demuestra esa técnica. Tenga en cuenta que esto es similar a lo que java.util.Timer hace bajo el capó, pero es más liviano.
import java.util.concurrent.TimeUnit;
public class DelaySample {
public static void main(String[] args) {
DelayUtil d = new DelayUtil();
System.out.println("started:"+ new Date());
d.delay(500);
System.out.println("half second after:"+ new Date());
d.delay(1, TimeUnit.MINUTES);
System.out.println("1 minute after:"+ new Date());
}
}
Implementación de DelayUtil
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class DelayUtil {
/**
* Delays the current thread execution.
* The thread loses ownership of any monitors.
* Quits immediately if the thread is interrupted
*
* @param duration the time duration in milliseconds
*/
public void delay(final long durationInMillis) {
delay(durationInMillis, TimeUnit.MILLISECONDS);
}
/**
* @param duration the time duration in the given {@code sourceUnit}
* @param unit
*/
public void delay(final long duration, final TimeUnit unit) {
long currentTime = System.currentTimeMillis();
long deadline = currentTime+unit.toMillis(duration);
ReentrantLock lock = new ReentrantLock();
Condition waitCondition = lock.newCondition();
while ((deadline-currentTime)>0) {
try {
lock.lockInterruptibly();
waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
} finally {
lock.unlock();
}
currentTime = System.currentTimeMillis();
}
}
}
podría usar la función Thread.Sleep ()
Thread.sleep(4000);
myfunction();
Su función se ejecutará después de 4 segundos. Sin embargo, esto podría detener todo el programa ...
ScheduledThreadPoolExecutor
tiene esta habilidad, pero es bastante pesado.
Timer
también tiene esta habilidad, pero abre varios hilos incluso si se usa solo una vez.
Aquí hay una implementación simple con una prueba (firma cercana a Handler.postDelayed() Android):
public class JavaUtil {
public static void postDelayed(final Runnable runnable, final long delayMillis) {
final long requested = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
long leftToSleep = requested + delayMillis - System.currentTimeMillis();
if (leftToSleep > 0) {
Thread.sleep(leftToSleep);
}
break;
} catch (InterruptedException ignored) {
}
}
runnable.run();
}
}).start();
}
}
Prueba:
@Test
public void testRunsOnlyOnce() throws InterruptedException {
long delay = 100;
int num = 0;
final AtomicInteger numAtomic = new AtomicInteger(num);
JavaUtil.postDelayed(new Runnable() {
@Override
public void run() {
numAtomic.incrementAndGet();
}
}, delay);
Assert.assertEquals(num, numAtomic.get());
Thread.sleep(delay + 10);
Assert.assertEquals(num + 1, numAtomic.get());
Thread.sleep(delay * 2);
Assert.assertEquals(num + 1, numAtomic.get());
}
Public static timer t;
public synchronized void startPollingTimer() {
if (t == null) {
TimerTask task = new TimerTask() {
@Override
public void run() {
//Do your work
}
};
t = new Timer();
t.scheduleAtFixedRate(task, 0, 1000);
}
}
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
EDITAR:
javadoc dice:
Después de que la última referencia en vivo a un objeto Timer desaparece y todas las tareas pendientes han completado la ejecución, el hilo de ejecución de tareas del temporizador finaliza con elegancia (y queda sujeto a la recolección de elementos no utilizados). Sin embargo, esto puede demorar arbitrariamente en ocurrir.