Temporizador en subproceso Java
Frecuentes
Visto 92,680 equipos
23
Tengo un hilo que se encarga de hacer algunos procesos. Quiero hacerlo para que este procesamiento se realice cada 3 segundos. He usado el código a continuación, pero cuando se inicia el hilo, no sucede nada. Supuse que cuando defino una tarea para mi temporizador, ejecuta automáticamente el ScheduledTask
dentro del intervalo de tiempo pero no hace nada en absoluto. ¿Qué me estoy perdiendo?
class temperatureUp extends Thread
{
@Override
public void run()
{
TimerTask increaseTemperature = new TimerTask(){
public void run() {
try {
//do the processing
} catch (InterruptedException ex) {}
}
};
Timer increaserTimer = new Timer("MyTimer");
increaserTimer.schedule(increaseTemperature, 3000);
}
};
5 Respuestas
26
Algunos errores en su fragmento de código:
- Extiendes el
Thread
clase, que no es realmente una buena práctica - Tiene
Timer
dentro de unThread
? Eso no tiene sentido como unTimer
funciona soloThread
.
Más bien debería (cuando/donde sea necesario), implementar un Runnable
ver aquí para un breve ejemplo, sin embargo, no puedo ver la necesidad tanto de un Thread
y Timer
en el fragmento que diste.
Por favor vea el siguiente ejemplo de un trabajo Timer
que simplemente incrementará el contador en uno cada vez que se llame (cada 3 segundos):
import java.util.Timer;
import java.util.TimerTask;
public class Test {
static int counter = 0;
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("TimerTask executing counter is: " + counter);
counter++;//increments the counter
}
};
Timer timer = new Timer("MyTimer");//create a new Timer
timer.scheduleAtFixedRate(timerTask, 30, 3000);//this line starts the timer at the same time its executed
}
}
Apéndice:
Hice un breve ejemplo de incorporar un Thread
en la mezcla. Así que ahora el TimerTask
simplemente incrementará counter
en 1 cada 3 segundos, y el Thread
mostrará counter
s valor durmiendo durante 1 segundo cada vez que comprueba el contador (se terminará a sí mismo y al temporizador después de counter==3
):
import java.util.Timer;
import java.util.TimerTask;
public class Test {
static int counter = 0;
static Timer timer;
public static void main(String[] args) {
//create timer task to increment counter
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
// System.out.println("TimerTask executing counter is: " + counter);
counter++;
}
};
//create thread to print counter value
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("Thread reading counter is: " + counter);
if (counter == 3) {
System.out.println("Counter has reached 3 now will terminate");
timer.cancel();//end the timer
break;//end this loop
}
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
});
timer = new Timer("MyTimer");//create a new timer
timer.scheduleAtFixedRate(timerTask, 30, 3000);//start timer in 30ms to increment counter
t.start();//start thread to display counter
}
}
Respondido 29 Jul 12, 10:07
1
Timer
& TimerTask
son legado
LA Timer
& TimerTask
las clases son ahora legado. Para ejecutar código en un momento determinado, o para ejecutar código repetidamente, use un servicio ejecutor programado.
Para citar el Timer
clase Javadoc:
Java 5.0 introdujo el paquete java.util.concurrent y una de las utilidades de concurrencia en él es ScheduledThreadPoolExecutor, que es un grupo de subprocesos para ejecutar tareas repetidamente a una velocidad o demora determinada. Es efectivamente un reemplazo más versátil para la combinación Timer/TimerTask, ya que permite múltiples subprocesos de servicio, acepta varias unidades de tiempo y no requiere la subclasificación de TimerTask (solo implemente Runnable). Configurar ScheduledThreadPoolExecutor con un subproceso lo hace equivalente a Timer.
Marco del ejecutor
En Java moderno, usamos el Marco de ejecutores en lugar de abordar directamente la Thread
clase.
Define tu tarea como una Runnable
or Callable
. Puede usar la sintaxis lambda compacta que se ve a continuación. O puede usar la sintaxis convencional para definir una clase que implemente el Runnable
(o Callable
) interfaz.
Haz una ScheduledExecutorService
objeto de ejecutar su Runnable
el código del objeto de vez en cuando.
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;
Runnable task = () -> {
System.out.println( "Doing my thing at: " + Instant.now() );
};
long initialDelay = 0L ;
long period = 3L ;
TimeUnit timeUnit = TimeUnit.SECONDS ;
scheduledExecutorService.submit( task , initialDelay, period , timeUnit ) ;
…
scheduledExecutorService.shutdown() ; // Stops any more tasks from being scheduled.
scheduledExecutorService.awaitTermination() ; // Waits until all currently running tasks are done/failed/canceled.
Tenga en cuenta que no estamos gestionando directamente ninguna Thread
objetos en el código anterior. La gestión de subprocesos es el trabajo del servicio ejecutor.
Consejos:
- Apague siempre su servicio ejecutor correctamente cuando ya no lo necesite o cuando su aplicación se cierre. De lo contrario, el grupo de subprocesos de respaldo puede continuar indefinidamente como un zombi 🧟♂️.
- Considere envolver el código de trabajo de su tarea en un try-catch. Cualquier excepción no detectada o error que llegue al servicio ejecutor programado da como resultado la detención silenciosa de la programación de más ejecuciones.
respondido 03 mar '21, 08:03
5
import java.util.Timer;
import java.util.TimerTask;
public class ThreadTimer extends TimerTask{
static int counter = 0;
public static void main(String [] args) {
Timer timer = new Timer("MyTimer");
timer.scheduleAtFixedRate(new ThreadTimer(), 30, 3000);
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("TimerTask executing counter is: " + counter);
counter++;
}
}
contestado el 20 de mayo de 14 a las 14:05
3
Para hacer algo cada tres segundos, debe usar scheduleAtFixedRate (ver javadoc).
Sin embargo, su código realmente no hace nada porque crea un hilo en el que inicia un temporizador justo antes de que se detenga la ejecución del hilo (no hay nada más que hacer). Cuando el temporizador (que es uno de un solo disparo) se activa, no hay hilo para interrumpir (la ejecución terminó antes).
class temperatureUp extends Thread
{
@Override
public void run()
{
TimerTask increaseTemperature = new TimerTask(){
public void run() {
try {
//do the processing
} catch (InterruptedException ex) {}
}
};
Timer increaserTimer = new Timer("MyTimer");
//start a 3 seconds timer 10ms later
increaserTimer.scheduleAtFixedRate(increaseTemperature, 3000, 10);
while(true) {
//give it some time to see timer triggering
doSomethingMeaningful();
}
}
Respondido 29 Jul 12, 08:07
2
Creo que el método que has usado tiene la firma schedule(TimerTask task, long delay)
. Entonces, en efecto, solo está retrasando la hora de inicio de la ÚNICA ejecución.
Para programarlo para que se ejecute cada 3 segundos, debe seguir este método schedule(TimerTask task, long delay, long period)
donde el terceras param se utiliza para dar el intervalo de período.
Puede consultar la definición de la clase Timer aquí para obtener más ayuda.
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
Respondido 29 Jul 12, 07:07
con la linea increaserTimer.schedule(increaseTemperature, 2000, 2000);
todavia no pasa nada! - Inspiración
@Elham: no lo noté antes, pero ¿está generando un nuevo hilo desde dentro de otro hilo? Este es un enfoque muy equivocado. Considere cambiar su estructura para que los subprocesos se generen y programen desde un nivel global. Aquí hay un enlace con un proyecto de ejemplo que le ayudará a cambiar su estructura: roseindia.net/java/example/java/util/CertainAndRepeatTime.shtml - afrin216
en otras palabras, no puedo usar Timer para programar la serie de acciones que realiza un hilo. ¿derecho? - Inspiración
@Elham: TimerTask en sí mismo puede llamarse Thread. Simplemente define la funcionalidad de su hilo en la función run () y está listo para comenzar. Simplemente no hay necesidad de extender la clase Thread y complicar su código. Debes tener una clase de padres, ¿rito? Genere una TimerTask de esa clase principal con un retraso programado y un intervalo. Asegúrese de agregar alguna condición de salida; de lo contrario, esta tarea seguirá ejecutándose hasta que la aplicación web esté activa. - afrin216
Este es un trabajo de clase. Necesito usar la clase thread para este programa. - Inspiración
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java multithreading timer or haz tu propia pregunta.
ibm.com/developerworks/java/library/j-schedule/index.html - nullpotent
¿Estás seguro de que estás creando un
temperatureUp
hilo y llamadastart()
¿en eso? Este código funciona bien para mí. - Jon Lin¿Por qué usarías tanto un hilo como un temporizador? El temporizador se ejecuta en su propio hilo - Esben Skov Pedersen
Creo que deberías repensar la estructura de tu programa. Debe considerar un temporizador global (no para cada hilo). ¿Qué pasa si los procesos tardan más de 3 segundos? ¿Cómo los terminarás con gracia? Debe proporcionar más información y más código, por favor :) - DMor
@AljoshaBre Todavía no sé qué tiene de malo este código. - Afflatus