Download Multithreading in Java

Document related concepts
no text concepts found
Transcript
CONCEPTES AVANÇATS DE SISTEMES OPERATIUS
Seminaris de CASO, curs 00/01 - 2Q
Multithreading in Java
<Noms i emails>
Elisa Gonzalez Boix([email protected])
Anna Mª Guitart Carrera([email protected])
Jose Ramon Romera Cabezas([email protected])
Cristina Santos Calles ([email protected])
Índex
–
–
–
–
–
–
–
–
Introducció
Creació
Estats d’un thread
Scheduling
Sincronisme
Excepcions
Modelo de hilos en Java
Thread en Linux con Java
SEMINARIS DE CASO
2
Introducció(I)
Java és més que un llenguatge de programació: qualsevol
programa en Java pot correr en qualsevol máquina on
estigui implementada i intal.lada la Java Virtual Machine
(JVM).
 Des dels inicis de Java es va pensar disenyar un llenguatge
orientat a objectes multitarea.
 Quan “s’inicia” la JVM, es crea un nou procés . Dintre d’ell
podran correr diversos threads.
 Java proporciona dos models de manegar els threads:

– Green (Implementació feta a nivell usuari)
– Native (Crides es mapejen a la plataforma que hi hagi al sistema)
SEMINARIS DE CASO
3
Introducció (II)

Java proposa un sistema robust i simple per crear,
configurar i executar threads:
– Molt poques intruccions per managar-ho.
• Advantages: Facititat d’ús i de revisió de codi (s’evitaran més facilment
deadlocks i inanicions).
• Inconvenients: Menor fexibilitat
– Dos maneres de crear-los.

Millor interacció amb l’usuari:
– Un programa que usi una interficie gràfica, la JVM
automàticament crea un thread per l’execució de mètodes i un pel
dibuix de finestres.
SEMINARIS DE CASO
4
Creació(I)

Passos a seguir per extendre la classe Thread :
– Extendre la classe java.lang.Thread
• public class MyThread extends Thread {
…}
– Sobreescriure el mètode run() a la subclasse
• public void run(){
System.out.println( getName()); }
– Crear una instància d’aquesta subclasse
• Thread thread1= new MyThread();
– Invocar el mètode start() a la instancia.
• thread1.start();
SEMINARIS DE CASO
5
Creació(II)

Exemple:
public class MyThread extends Thread{
public void run(){
System.out.println(getName());
}
}
public static void main(){
Thread t= new MyThread();
t.start;
}
SEMINARIS DE CASO
6
Creació(III)
Extenent la classe Thread es poden heretar mètodes i
variables de la classe pare. Però, per restriccions del Java,
només es pot extendre una vegada de la classe pare.
 Aquesta serà l’opció que s’usarà, normalment, quan creem
alguna classe que ninguna altra hereti d’ella.
 Però, en alguns casos ens interessarà extendre alguna de
les funcionalitats a altres classes. Llavors, haurem de dotar
de la qualitat de thread mitjançant interfície Runnable.

SEMINARIS DE CASO
7
Creació(IV)

Passos a seguir per implementar la interfície Runnable:
– Definir la capçalera de la classe que implementa la interfície
Runnable.
• public class nom_classe extends nom_clase_a_heretar implements
Runnable{
…. }
– Implemetar el mètode run() i un objecte de tipo Thread que
contingui el codi del fluxe concurrent que volem crear.
• public void run(){
…}
SEMINARIS DE CASO
8
Creació(V)
– El constructor de la classe Thread rebra un argument que ha de
ser una instància de la classe que implementa la interface
Runnable.

Exemple:
public class ThreadTest{
public static void main(String args[]{
Xyz r = new XYZ();
Thread t = new Thread( r );
}
}
class Xyz implements Runnable {
int i;
SEMINARIS DE CASO
9
Creació(VI)
public void run(){
while (true){
System.out.println(“Hello” + i++);
if (i==50) break;
}
}
}
SEMINARIS DE CASO
10
Estats d’un thread (I)

Durant la seva vida, un thread pot trobar-se en diferents
estats:
Sleep()
o
thread join() s
o
interrupt()
nuevo
Start()
ejecutable
En
ejecución
wait()
Bloqueado en la
cola wait de un
objeto
Lock
available
Notify()
interrupt()
Otras
causas de
bloqueo
Sleep
o
join
Run()
completes
Muerte
Synchronized()
Bloqueado en la
cola de
bloqueados
SEMINARIS DE CASO
11
Estats d’un thread (II):Nou Thread
En aquest estat és un thread buit.
 El sistema no ha designat cap recurs per ell.
 En aquest estat

– s’arrenca amb start()
– qualsevol altre mètode genera una excepció de tipus :
IllegalThreadStateException
SEMINARIS DE CASO
12
Estats d’un thread (III):Parada

S’hi arriba:
– Amb la invocació dels mètodes:
• join() sobre un altre thread
• Sleep()
– Quan el thread es bloqueja per E/S
– Quan el thread crida wait()

Recuperació a l’estat executable:
– Si està a E/S
en acabar l’execució de la comanda d’E/S
– Si està adormit
– Si ha fet un join
passat el temps especificat
quan acabi el procés sobre el que ha fet el join
SEMINARIS DE CASO
13
Estats d’un thread (IV): Parada

Recuperació a l’estat executable
– Si un thread està esperant per una condició, cada cop que la
variable que controla la condició varïi s’ha de fer un notify() o
notifyAll()
SEMINARIS DE CASO
14
Estats d’un thread (V): Mort

S’hi arriba:
– Quan s’acaba l’execució del run()
– Invocant el mètode destroy() del thread
SEMINARIS DE CASO
15
Scheduling (I)

Java té un Scheduler:
– Llista de processos que monitoritza tots els threads que s’estan
executant en tots els programes.
– Decideix quins threads s’executen i quins es troben preparats per
a l’execució, en funció de:
• Prioritat del thread
• Indicador daemon del thread.
SEMINARIS DE CASO
16
Scheduling(II)

L’scheduler pot seguir un patró preemptiu o no-preemptiu
– patró preemptiu: l’scheduler proporciona un segment de temps a
cada thread per utilitzar el sistema. En passar l’interval de temps li
treu el sistema i el cedeix a un altre thread.
– patró no-preemptiu:El thread té assignat el sistema fins que acaba
l’execució o fa un E/S, yield() o sleep().
SEMINARIS DE CASO
17
Scheduling(III):Prioritats
El rang de prioritats oscil.la entre 1 i 10
 La prioritat per defecte d’un thread és NORM_PRIORITY
(prioritat de 5)
 MIN_PRIORITY (prioritat de 1)
 MAX_PRIOROTY (prioritat de 10)
 Mètode getPriority() per conèixer el valor actual de la
prioritat del thread.

SEMINARIS DE CASO
18
Scheduling(IV):Threads daemon
S’anomenen també serveis
 S’executen amb prioritat baixa i proporcionen un servei
bàsic a un programa quan l’activitat de la màquina és
reduida
 Exemple: garbage_collector
 setDaemon() per passar a ser daemon (abans de l’start())
 isDaemon() per saber si és daemon.

SEMINARIS DE CASO
19
Excepcions(I)
Les excepcions ens proporcionen una manera senzilla de
matar un thread des d’un altre.
 Es generen des d’un punt del codi i ascendeixen als pares
d’aquest codi.
 Si no es tracten donen un error en temps d’execució i el
programa finalitza.
 Acaba éssent difícil de controlar, no aconsellable usar en
programes grans.

SEMINARIS DE CASO
20
Sincronització(I)

mètodes:
– wait():
• El mètode wait() es heretat de la classe Object.
• Proporciona la posibilitat de comunicació entre Threads.
• Utilització:
– Si un thread executa el metode wait d’un objecte, el thread es
bloquejarà en la “cua” d’aquest objecte.
– El thread no es desbloquejarà fins que un altre thread executi el
mètode notify() o notifyAll()
• Detalls:
– L’ordre de bloqueix és irrellevant a l’hora d’extreure de la cua.
SEMINARIS DE CASO
21
Sincronització(II)

mètodes:
– notify():
• El mètode notify() es heretat de la classe Object.
• Proporciona la posibilitat de comunicació entre Threads.
• Utilització:
– Si un thread executa el métode notify() d’un objecte, el thread es
desbloquejarà un element de la “cua” d’aquest objecte.
• Detalls:
– Els elements de la cua no segueixen cap ordre segons l’inserció, així
doncs no podem fer cap suposició sobre el thread que es
desbloquejarà.
SEMINARIS DE CASO
22
Sincronització(III)

mètodes:
– notifyAll():
• El mètode notify() es heretat de la classe Object.
• Proporciona la posibilitat de comunicació entre Threads.
• Serveix per desbloquejar tots els threads bloquejats al objecte.
SEMINARIS DE CASO
23
Sincronització(IV)

mètodes:
– join():
• El mètode join() es heretat de la classe thread.
• Proporciona la posibilitat de comunicació entre Threads.
• Utilizació:
– Bloqueix el thread actual fins que el thread sobre el que s’ha executat
el join() termini.
SEMINARIS DE CASO
24
Modelo de hilos en JAVA(I)

Modelo de programación con hilos en JAVA:
– No tenemos el control sobre el modelo de manejo de hilos.
– Los detalles se establecen entre JVM y el sistema operativo.
– La eleccion del modelo puede ser impuesta por el usuario
• –green
• –native
Esto fuerza a escribir codigo mas portable( ventaja, desventaja ).

Espacio para manejo de hilos
– Java proporciona dos modelos:
• GREEN
• NATIVE
SEMINARIS DE CASO
25
Modelo de hilos en JAVA(II)

GREEN
– Tienen la API definida por Sun ( igual para todas las plataformas )
– Su implementacion esta hecha con hilos en espacio de usuario.

NATIVOS
– Se implementan con el API proporcionada por la plataforma nativa
– Windows y Solaris proporcionan API nativa propietarias
– Otras plataformas de UNIX proporcionan la API pthreads de POSIX P1003.1c
(ISO)
– El nivel de implementacion suele ser a nivel Kernel, aunque existen
implementaciones a nivel Usuario ( primeras implementaciones en HP-UX )
SEMINARIS DE CASO
26
Modelo de hilos en JAVA(III)

Preempción
– DEF: Capacidad del planificador para interrumpir un hilo y introducir otro a
ejecutar
– Java no requiere preempcion necesariamente, dependera de la
implementacion.
– Por dicha razon tenemos dos modelos de control de hilos:
•
Modelo donde no hay preempcion y por lo tanto el bloqueo del hilo
es voluntario: explicitamente ( read() ... ), implicitamente ( Thread.yield() o
Thread.sleep()).
•
Modelo donde el hilo puede ser interrumpido en cualquier momento,
con lo que se hace necesario el uso de mecanismos de sincronizacion.
SEMINARIS DE CASO
27
Modelo de hilos en JAVA(IV)
SEMINARIS DE CASO
28
Threads en linux con JAVA(I)

Introducción:
– Linux incluye la biblioteca POSIX pthread, totalmente operativa.
– Toda aplicacón que utilice dicha biblioteca esta utilizando threads
en el kernel con preempción.
– En Linux la alternancia de threads en el kernel es equiparable a la
de espacio usuario, con lo que no se hace necesario modelo en
espacio usuario o hibrido.
– El mecanismo de manejo de threads se construye con una única
llamada a sistema _clone( ), dicha llamada no es visible a
programadores JAVA ni es recomendable su utilización en C/C++
(poco transportable).
SEMINARIS DE CASO
29
Threads en linux con JAVA(II)

Introducción:
– Debido a la utilizacion de la llamada _clone, cada thread tendrá
un ID de proceso , con lo que tendremos 2 consecuencias:
• El proceso Multithread se muestra con muchas entradas en la lista de
procesos ( comando shell ps ), la identificacion entre threads se hace difícil,
aunque se pueden intuir mirando :
– /proc/<pid>/maps ( mapa de la zona de memoria ), donde los hilos
relacionados tendran un mapa identico
– /proc/<pid>/status los valores contenidos seran iguales para todos
los Vm* .
– /proc/<pid>/ environ o /proc/<pid>/fds , tendran datos iguales
SEMINARIS DE CASO
30
Threads en linux con JAVA(III)

Introducción:
– La tabla de procesos tiene un espacio limitado por defecto a 256
entradas por usuario y 512 en total.
– Tendríamos limitado el nº de threads,
• Aunque se puede aumentar si modificamos en el fichero
include/linux/tasks.h los valores de:
– NR_TASKS y
– MAX_TASKS_PER_USER,
entonces podremos soportar hasta 4092 procesos en entornos de
Linux ( x86 )
MAKE.
• Aunque podremos personalizar nuestro kernel el hecho de utilizar muchos
threads es signo de programación perezosa y puede llevar a un
colapso
utilizar metodo de encolamiento.
SEMINARIS DE CASO
31
Threads en linux con JAVA(IV)

Preempcion de hilos en linux
– Dado el numero de versiones que hay de la JVM, las
posibilidades son diversas:
• El puerto Blackdown JDK ofrece el manejo de hilos green y nativos:
– La version nativa utiliza una planificacion con preempcion
– La version de hilos green no la utiliza
• Otros entornos como Kaffe y gcj pueden variar su comportamiento segun
las opciones elegidas en tiempo de configuracion
SEMINARIS DE CASO
32
Threads en linux con Java(V)

Prioridades de hilos
– Las prioridades no tienen efecto bajo e JDK en Linux, aunque
permite un cierto control sobre prioridades, pero eso solo es
posible para procesos ejecutados como usuario root.
– El Blackdown ni siquiera intenta establecer prioridades.
SEMINARIS DE CASO
33
Bibliografia
API JDK 1.3
 Manual de usuario y tuturial Java 2

– Agustin Froufe , Ed Ra-Ma

Curso de Java avanzado
– Jedi
SEMINARIS DE CASO
34