Tema 6. Threads: programas multitarea

Anuncio
Tema 6. Threads: programas
multitarea
„
„
„
„
„
„
„
„
Procesos e hilos
Creación de threads
Ciclo de vida de un thread
Sincronización
Prioridades
Grupos de threads
Relación de métodos
Ejemplo sincronización
1
Procesos e hilos
„
Programa multitarea:
„
„
„
Es un programa en ejecución
Posee su propia memoria
Thread o hilo:
„
„
Realización “simultánea” de 2 o más
actividades
Proceso:
„
„
Proceso
Flujo de ejecución dentro de un
proceso
Un proceso puede tener varios
hilos en ejecución
Threads
2
Creación de Threads
„
Opción 1
„
„
„
Crear una clase derivada de la clase
java.lang.Thread
Sobrecargar el método run()
Opción 2
„
„
„
Declarar una clase que implemente la interface
java.lang.Runnable
Definir el método run()
Crear un objeto de tipo Thread pasándole al
constructor el objeto de la nueva clase
3
Creación de un hilo derivando
de la clase Thread
class Hilo1 extends Thread
{
public Hilo1(String str)
{
super(str);
}
public void run()
{
for(int i=0;i<10;i++)
System.out.println("Thread: " +
getName());
}
}
public class TestHilo1
{
public static void main(String arg[])
{
Hilo1 miHilo = new Hilo1("Hilo
de prueba");
miHilo.start();
}
}
4
Creación de un hilo implementando
la interface Runnable
class Hilo2 implements Runnable
{
String nombreThread;
public Hilo2(String str)
{
nombreThread = str;
}
public void run()
{
for(int i=0;i<10;i++)
System.out.println("Thread: " +
nombreThread);
}
}
public class TestHilo2
{
public static void main(String
arg[])
{
Hilo2 p = new Hilo2("Hilo
de prueba");
Thread miHilo = new
Thread(p);
miHilo.start();
}
}
5
Ciclo de vida de un Thread
6
Ejecución de un nuevo Thread
„
La creación de un Thread no implica su
ejecución
„
„
„
Hay que inicializarlo con el método start()
El método start() llama al método run()
Después de ejecutar start(), el thread está
en estado ejecutable (runnable)
„
No quiere decir que se esté ejecutando en todo
momento, ya que debe compartir la CPU con el
resto de threads en estado runnable
7
Detención temporal (i)
„
„
Los tiempos de CPU que el sistema asigna a
los threads en estado runnable se emplean
en ejecutar el método run() de cada thread
Un thread puede renunciar a su tiempo de
CPU y otorgárselo al sistema para asignárselo
a otro thread → método yield()
„
Si ningún thread requiere la CPU para una
actividad intensiva, el sistema volverá asignar
nuevo tiempo al thread generoso
8
Detención temporal (ii)
„
Formas de parar un thread (not runnable):
„
„
„
„
„
„
Ejecutando el método sleep() → detiene el thread el
tiempo establecido. Suele llamarse desde el método run()
Mediante el método wait() → detiene el thread hasta que
se ejecuten los métodos notify() o notifyAll()
Cuando el thread está esperando realizar operaciones de
E/S
Cuando el thread está intentando llamar a un método
syncronized de un objeto, y el objeto está bloqueado por
otro thread
El thread pasa a estado runnable cuando cese
alguna de las condiciones anteriores
La clase Thread dispone de los métodos stop() y
suspend(), pero su uso se desaconseja
9
Detención temporal (iii)
„
„
Forma preferible de detener un thread: utilización
conjunta de los métodos wait() y notifyAll()
Modos de llamar a wait()
1)
„
„
Indicando el tiempo máximo que debe estar parado
Si se ejecuta notify() o notifyAll(), que indican la
liberación de los objetos bloqueados, el thread continuará
sin esperar a concluir el tiempo
2)
„
„
„
Sin argumentos
El thread permanece parado hasta reinicializarlo con los
métodos notify() o notifyAll()
Los métodos wait() y notify() deben estar incluidos
en un método synchronized
10
Sincronización
„
Se utiliza cuando:
„
„
„
Los métodos que accedan a un recurso compartido
deben declararse como synchronized
„
„
„
2 o más threads intentan acceder al mismo recurso al
mismo tiempo
Un thread debe esperar a que estén listos los datos que le
debe suministrar otro thread
Ej: public synchronized void metodoSincronizado()
Si el método accede a un recurso, Java bloquea el recurso,
de forma que el resto de threads no pueden acceder al
mismo hasta que el primero finalice su tarea
Bloquear un recurso u objeto:
„
Sobre el objeto no pueden actuar 2 métodos sincronizados
al mismo tiempo
11
Niveles de bloqueo
„
A nivel de objetos
„
„
„
„
Se declaran todos los métodos de la clase como
synchronized
Al ejecutar un método sobre un objeto, el sistema bloquea
dicho objeto, permaneciendo a la espera cualquier thread
que intente ejecutar algún método sincronizado del mismo
objeto
Si hay varios objetos, es posible tener distintos threads
ejecutando métodos sobre diversos objetos
A nivel de clases
„
Se corresponde con los métodos de clase o static, y por
tanto con las variables de clase o static
12
Prioridades
„
„
„
Es posible establecer prioridades en los threads para
repartir el tiempo de la CPU
Las prioridades vienen definidas por variables
miembro (de tipo entero) de la clase Thread.
Constantes asociadas a prioridades:
„
„
„
„
MAX_PRIORITY: máxima prioridad
MIN_PRIORITY: mínima prioridad
NORM_PRIORITY: prioridad por defecto
Métodos:
„
„
Para modificar la prioridad → método setPriority()
Para obtener su prioridad → método getPriority()
13
Grupos de threads (i)
„
Un hilo debe pertenecer a un grupo de hilos
(ThreadGroup)
„
„
Por defecto cuando se crea un thread pertenece al
ThreadGroup del thread desde el que ha sido creado.
„
„
Los grupos de threads permiten manejar múltiples threads como
un solo objeto
Si no se crea ningún ThreadGroup, pertenecerá al
ThreadGroup llamado main, que se crea al arrancar el programa
Para que un thread pertenezca a un grupo, hay que
indicarlo al crearlo:
„
„
„
Thread (ThreadGroup grupo, Runnable destino)
Thread (ThreadGroup grupo, String nombre)
Thread (ThreadGroup grupo, Runnable destino, String nombre)
14
Grupos de threads (ii)
„
„
„
„
Un ThreadGroup debe pertenecer a otro ThreadGroup
Si no se especifica ninguno, pertenecerá al ThreadGroup
desde el que ha sido creado (por defecto el main)
Constructores de ThreadGroup:
„ ThreadGroup(ThreadGroup parent, String nombre);
„ ThreadGroup(String name); → toma como parent el
ThreadGroup al cual pertenece el thread desde el que se
crea
Ejemplo:
ThreadGroup miThreadGroup = new ThreadGroup(“mi grupo”);
Thread miThread = new Thread(miThreadGroup, “hilo de mi grupo”);
15
Relación de métodos (1)
Clase Thread
„
Métodos estáticos
„
„
„
„
Thread currentThread(): Devuelve la tarea que se está
ejecutando
void yield(): Cede el control a otra tarea de la misma
prioridad
void sleep (long): Duerme la tarea los ms especificados
Métodos de instancia
„
„
„
„
„
„
void start(): Comienza la ejecución del Thread
void run(): Cuerpo de la tarea
void setPriority(int): Asigna la prioridad
int getPriority(): Devuelve la prioridad
void setName(String): Asigna un nombre
String getName(): Devuelve el nombre
16
Relación de métodos (2)
Clase Object
„
Métodos para sincronización
„
public final void wait()
„
„
public final void notify()
„
„
„
El thread actual espera hasta que otro thread
utilice notify() o nofityAll()
Despierta a un único thread que estuviera
esperando
Si hay varios, lo elige arbitrariamente
public final void notifyAll()
„
Despierta a todos los threads que estuvieran
esperando
17
Ejemplo sincronización (1)
HiloEscritor
valor
HiloLector
Dato
int obtener()
void asignar(int)
Funcionamiento:
- El escritor escribe 5 datos
- El lector lee 5 datos
- Se debe leer cada dato escrito
18
Ejemplo sincronización (2)
public class EjSincronizar
{
public static void main(String[] args)
{
Dato d = new Dato();
HiloEscritor esc=new HiloEscritor(d);
HiloLector lec=new HiloLector(d);
}
}
esc.start();
lec.start();
19
Ejemplo sincronización (3)
class HiloLector extends Thread
{
private Dato dato;
public HiloLector(Dato d)
{
dato = d;
}
}
public void run()
{
int valor;
for(int i=0;i<5;i++){
valor = dato.obtener();
}
}
20
Ejemplo sincronización (4)
class HiloEscritor extends Thread
{
private Dato dato;
public HiloEscritor(Dato d)
{
dato = d;
}
}
public void run()
{
int valor;
for(int i=0;i<5;i++){
dato.asignar(i);
}
}
21
Ejemplo sincronización (5)
class Dato
{
private boolean disponible;
private int valor;
public Dato()
{
disponible = false;
}
public synchronized int obtener()
{
}
}
public synchronized void asignar(int v)
{
}
22
Ejemplo sincronización (6)
public synchronized int obtener()
{
while(disponible==false){
try{
wait();
}
catch(InterruptedException e){}
}
disponible = false;
System.out.println("Leyendo: " +valor);
notifyAll();
return valor;
}
23
Ejemplo sincronización (7)
public synchronized void asignar(int v)
{
while(disponible==true){
try{
wait();
}
catch(InterruptedException e){}
}
valor = v;
System.out.println("Escribiendo: " +valor);
disponible = true;
notifyAll();
}
24
Descargar