Publicado el 14 de Enero del 2017
1.041 visualizaciones desde el 14 de Enero del 2017
508,9 KB
30 paginas
Creado hace 15a (26/10/2009)
PROGRAMACION CONCURRENTE Y
DISTRIBUIDA
IV.2 Tareas periódicas: Timer, TimerTask y
ScheduledThreadPoolExecutor classes
J.M. Drake
L.Barros
Notas:
1
Esperas temporizadas
Las sentencias básicas de temporización en Java son las
esperas temporizadas:
De la clase Thread:
public static void sleep(long millis) throws InterruptedException;
public static void sleep(long millis, int nanos)
throws InterruptedException;
De la clase Object:
public final void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos)
La temporización hace referencia a una espera fijada en tiempo
relativo
throws InterruptedEsception;
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
2
Notas:
Tarea periódica basada en esperas temporizadas (1)
public class PeriodicTask {
Thread thread;
public interface Task{ public void oper(); }
public void periodicExecution(final Task task, final int periodIn_ms){
thread=new Thread( new Runnable(){
public void run(){
while(!Thread.interrupted()){
task.oper();
try{ Thread.sleep(periodIn_ms);
}catch(InterruptedException ie){ Thread.currentThread().interrupt();};
}
}
});
thread.start();
}
public void cancel(){Thread.interrupt();}
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
3
}
Notas:
Tarea periódica basada en esperas temporizadas (2)
public static void main(String[] args) {
//Define la tarea
final class Print implements Task{
public void oper(){
System.out.println(“Nueva Ejecución: "+ System.currentTimeMillis());}
}
Print p=new Print();
// Define la tarea periodica que ejecuta la tarea
PeriodicTask pt= new PeriodicTask();
pt.periodicExecution(new Print(), 1000);
// Espera un tiempo
try{ Thread.sleep(10000);}
catch (InterruptedException e){};
// Cancela la ejecución
pt.cancel();
}
Nueva Ejecución: 1194377159484
Nueva Ejecución: 1194377160484
Nueva Ejecución: 1194377161484
Nueva Ejecución: 1194377162484
Nueva Ejecución: 1194377163484
Nueva Ejecución: 1194377164484
Nueva Ejecución: 1194377165500
Nueva Ejecución: 1194377166500
Nueva Ejecución: 1194377167500
Nueva Ejecución: 1194377168500
Nueva Ejecución: 1194377169500
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
4
Notas:
Problema de las tareas periodicas basada en sleep
Si se basa en un tiempo relativo, su periodo es siempre
superior al previsto:
Periodo requerido
Op.
Sleep()
Op.
Sleep()
Op.
Sleep()
Op.
Periodo real siempre mayor que el requerido
Las tareas basadas en sleep until un tiempo absoluto tienen un
periodo medio igual al programado:
Periodo requerido
SleepUntil()
Op.
SleepUntil()
Op.
Op.
SleepUntil()
Op.
SleepUntil()
Op.
Periodo real en promedio igual al requerido (presenta jitter-fluctuaciones)
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
5
Notas:
Problema de tareas basadas en tiempos absolutos
Las tareas periódicas basadas en tiempos absolutos pueden
presentar altos jitters:
T1
T2
Periodo requerido
T4
T3
T5
T6
Op.
SleepUntil()
Op.
SleepUntil()
Tarea de mayor prioridad
Op. Op. Op.
Op.
SleepUntil()
Op.
T1
T2
T3 T4 T5
T6
La tarea periódica presenta un alto jitter
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
6
Notas:
Tarea periódica basada en plazoabsolutos
public class PeriodicTask {
Thread thread;
long nextExecution;
public interface Task{ public void oper(); }
public void periodicExecution(final Task task, final int periodIn_ms){
thread=new Thread( new Runnable(){
public void run(){
nextExecution= System.currentTimeMillis();
while(!Thread.interrupted()){
nextExecution= nextExecution+periodIn_ms;
task.oper();
try{ Thread.sleep(nextExecution-System.currentTimeMillis());
}catch(InterruptedException ie){ Thread.currentThread().interrupt();};
} } });
thread.start();
}.....
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
7
Notas:
Clase Timer
Es un recurso activo que permite programar tareas:
para que se ejecuten en un tiempo futuro.
o para que se ejecuten periódicamente.
Se basa en un único Thread de soporte, dentro del que se
ejecutan todas las tareas que se le programan,
secuencialmente. Si la ejecución de una tarea tarda más de lo
previsto, las siguientes pueden retrasarse.
Tiene un diseño muy eficiente, y puede gestionar la ejecución
de miles de tareas.
Es seguro para ser accedido por múltiples thread, sin requerir
una sincronización específica.
No ofrece garantías de tiempo real estricto, ya que se basa en
sentencias del tipo Object.wait(long).
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
8
Notas:
Constructores de la clase Timer
Timer()
//Crea un nuevo Timer
Timer(boolean isDaemon)
// Crea un nuevo timer y declara el thread interno com daemon si el parámetro es
true.
Timer(String name)
// Crea un nuevo timer y le asocia a su thread interno el nombre que se especifica.
Timer(String name, boolean isDaemon)
// Crea un nuevo timer con nombre y control de finalización como daemon o no.
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
9
Notas:
El Timer desaparece cuando ya no hay threads de usuario
Métodos de la clase Timer (1)
void cancel() //Terminates this timer, discarding any currently scheduled tasks.
int purge()
//Removes all cancelled tasks from this timer's task queue.
void schedule(TimerTask task, Date time)
// Programa la tarea para la ejecución una sóla vez y en el tiempo indicado.
void schedule(TimerTask task, Date firstTime, long period)
// Programa la tarea para la ejecución a partir de firstTime y luego
// periódicamente cada period ms.
void schedule(TimerTask task, long delay)
// Programa la tarea para la ejecución una sóla vez tras el retraso especificado.
void schedule(TimerTask task, long delay, long period)
// Programa la tarea para la ejecución tras un retraso delay y luego
// periódicamente cada periodo ms.
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
10
Notas:
Métodos de la clase Timer (2)
void scheduleAtFixedRate(TimerTask task, Date firstTime,
long period)
// Programa la tarea para la ejecución con programación en instante fijo hasta
// que se cancele , empezando en firstTime y ejecutándose cada period ms.
void scheduleAtFixedDelay(TimerTask task, long delay,
long period)
// Programa la tarea para la ejecución con programación en instante fijo hasta
// que se cancele , tras un retraso delay y ejecutándose cada period ms.
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
11
Notas:
Ejemplo I: Reloj segundero de pantalla
Ejemplo: queremos pintar un reloj en pantalla, cada segundo debemos mover
o repintar el segundero.
Solución: a la clase Timer le decimos cuando queremos el aviso (por ejemplo,
un aviso cada segundo en el caso del reloj) y ella se encarga de llamar a un
método que nosotros hayamos implementado.
Resultado:El resultado es que ese método (el que pinta el segundero en la
pantalla), se llamará cada cierto tiempo (una vez por segundo en el caso del
reloj).
Scheduled():
Problema: es posible que el ordenador esté ocupado haciendo otras cosas, con
lo que el aviso (pintado) nos puede llegar con un cierto retraso.
Con esta opción el retraso se acumula de una llamada a otra.
Si el ordenador está muy atareado y nos da avisos cada 1.1 segundos en vez
de cada 1, el primer aviso lo recibimos en el segundo 1.1, el segundo en el
2.2, el tercero en el 3.3, etc, etc.
Si hacemos nuestro reloj de esta forma, cogerá adelantos o retrasos
importantes en poco tiempo.
Notas:
Ejemplo II: Reloj segundero de pantalla
scheduleAtFixedRate():
Con estos métodos los avisos son relativos al primer aviso, de esta forma,
si hay retraso en un aviso, no influye en cuando se produce el siguiente.
Igual que antes, si el ordenador está muy ocupado y da avisos cada 1.1
segundos en vez de cada segundo, el primer aviso se recibirá en el
segundo 1.1, el segundo en el 2.1, el tercero en el 3.1, etc.
El retraso no se va acumulando.
Está claro que para hacer un reloj, como es nuestro ejemplo, debemos
usar la segunda forma (métodos scheduleAtFixedRate() en vez de
schedule()).
Notas:
Clase TimerTask
Clase abstracta que define una tarea que puede ser planificada
para la ejecución en un timer, bien una sóla vez o de forma
repetida.
Constructor:
protected TimerTask() // Creates a new timer task.
Métodos:
boolean cancel() // Cancels this timer task.
abstract void run() // The action to be performed by this timer task.
long scheduledExecutionTime()
// Returns the scheduled execution time of the most recent actual execution
of this task.
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
14
Notas:
Ejemplo de uso de scheduledExecutionTime() method
Public class MyTimerTask extends TimerTask{
public void run(){
...
if (System.currentTimeMillis-scheduledExecutionTime()>5000){
// Ya han transcurrido mas de 5 segundos desde que se ejecutó
// ínicio la ejecución y debe terminarse
return;
}
...
}
Procodis’09: IV.2- Tareas periódicas José M.Drake L.Barros
15
Notas:
Formas de finalización de un Timer
Invocando cancel sobre el timer.
Haciendo del Timer un demonio mediante new Timer(true). Si
ma única hebra que abandona el programa es daemon, el
programa finaliza.
Una vez terminadas todas las tareas configuradas, se borran
todas las referencias del objeto Timer.
Invocando el método de sistema System.exit, que hace que
todo el programa (con todas sus hebras) finalice.
Notas:
Ejemplo de planificación de tarea con Timer
import java.util.Timer;
impo
Comentarios de: PROGRAMACION CONCURRENTE Y DISTRIBUIDA - IV.2 Tareas periódicas: Timer, TimerTask y ScheduledThreadPoolExecutor classes (0)
No hay comentarios