Temporizador en subproceso Java

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);

    }
};

preguntado el 29 de julio de 12 a las 07:07

¿Estás seguro de que estás creando un temperatureUp hilo y llamada start() ¿en eso? Este código funciona bien para mí. -

¿Por qué usarías tanto un hilo como un temporizador? El temporizador se ejecuta en su propio hilo -

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 :) -

@AljoshaBre Todavía no sé qué tiene de malo este código. -

5 Respuestas

Algunos errores en su fragmento de código:

  • Extiendes el Thread clase, que no es realmente una buena práctica
  • Tiene Timer dentro de un Thread? Eso no tiene sentido como un Timer funciona solo Thread.

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á counters 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

Timer & TimerTask son legado

Las 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

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

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

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 or haz tu propia pregunta.