Multithreading%20and%20Thread%20Synchronization%20in%20Java - PowerPoint PPT Presentation

About This Presentation
Title:

Multithreading%20and%20Thread%20Synchronization%20in%20Java

Description:

CONCEPTES AVAN ATS DE SISTEMES OPERATIUS. Departament d'Arquitectura de Computadors ... El thread2 intenta escribir en un fichero cerrado, falla el programa. ... – PowerPoint PPT presentation

Number of Views:115
Avg rating:3.0/5.0
Slides: 38
Provided by: studie
Category:

less

Transcript and Presenter's Notes

Title: Multithreading%20and%20Thread%20Synchronization%20in%20Java


1
Multithreading and Thread Synchronization in Java
  • Adolfo Alonso Puig e6743863_at_est.fib.upc.es
  • Eva Perales Laguna e0993693_at_est.fib.upc.es

2
Que es un thread en Java
  • Un thread representa una CPU virtual que ejecuta
    el código de un programa.
  • Se compone de 3 partes
  • Procesador vrtual
  • Código
  • Datos

3
Creación de un thread (I)
  • Tenemos dos posibilidades a la hora de crear
    threads
  • Crear una instancia de una clase que implemente
    el interface Runnable
  • Debe proveer una implementación del método run()
  • miClase th new miClase()

4
Creación de un thread (II)
  • Extender la clase Thread
  • Redefinición del método run() de la superclase
  • public class MyThread extends Thread
  • MyThread th new MyThread()
  • Problema Java sólo permite la herencia simple,no
    será posible extender ninguna otra clase cuando
    extendemos la clase Thread.

5
Inicio de un thread
  • Al crear un thread no iniciamos su ejecución de
    forma automática. Para iniciarlo debemos invocar
    a su método start()
  • th.start()
  • El thread esta preparado para ejecutarse

6
Control básico de threads (I)
  • Finalización de un thread
  • Podemos detener un thread utilizando un flag que
    indique a su método run que debe terminar su
    ejecución.Una vez finalizado no puede volver a
    ser ejecutado
  • En versiones anteriores de JDK se usaba el método
    stop() pero esta Deprecated.
  • Verificación del estado de un thread
  • Para saber si un thread puede ser elegido para
    ejecución utilizamos el método isAlive()

7
Control básico de threads (II)
  • Bloqueo de un thread
  • El método sleep() permite detener un thread
    durante un periodo de tiempo definido por el
    usuario.
  • El método join() bloquea el thread actual hasta
    que el thread sobre el cual ha sido ejecutado el
    join termina.
  • En versiones anteriores de JDK se proporcionaba
    el método suspend() que bloqueaba el thread hasta
    que fuera nuevamente activado por el método
    resume()

8
Estados de un thread
9
Planificación de threads
  • Se basa en el modelo de prioridades y no en la
    multiplexacion del tiempo de CPU (timeslicing)
  • Para decidir que thread se ejecuta el
    planificador se fija en la prioridad de cada uno
    y elige el de prioridad más alta
  • El método yield() puede ser utilizado para
    permitir a otros threads con la misma prioridad
    la posibilidad de ejecutarse

10
Prioridades
  • La prioridad de un thread puede tener un valor
    entero entre MIN_PRIORITY y MAX_PRIORITY
    (constantes de la clase java.lang.Thread)
  • La prioridad de un nuevo thread es la misma del
    thread en ejecución.
  • El método getPriority() devuelve el valor actual
    de la prioridad del thread.
  • El método setPriority() modifica la prioridad del
    thread

11
Problemas con threads Race condition
  • Es el problema más común y a la vez el más
    insidioso que se produce con los threads. Aparece
    cuando dos o más threads acceden al mismo recurso
    a la vez.
  • El problema se genera de forma aleatoria
    produciendo un abrazo mortal (deadlock) entre
    todos los threads, datos inconsistentes o fallo
    del programa.

12
Ejemplo de race condition (I)
  • class UnsafeLogger
  • // recurso crítico, podria ser una lista
    enlazada, vector o cualquier recurso
  • private File m_file
  • public void write ( String s )
  • // tratamiento de ficheros simplificado
  • m_file.open ( "filename.log" )
  • m_file.write ( s )
  • m_file.close ( )

13
Ejemplo de race condition (II)
  • class Writer extends Thread
  • private UnsafeLogger m_log
  • private String m_threadID
  • Writer ( UnsafeLogger log, String threadID )
  • m_log log
  • m_threadID threadID
  • public void run ( )
  • while( true )
  • m_log.write ( m_threadID )
  • m_log.write ( " is alive\n" )

14
Ejemplo de race condition (III)
  • class MainClass
  • public static void main ( )
  • UnsafeLogger log new UnsafeLogger (
    )
  • Writer writer1 new Writer ( log,
    "thread1" )
  • Writer writer2 new Writer ( log,
    "thread2" )
  • // inicia los threads
  • writer1.start ( )
  • writer2.start ( )

15
Posibles ejecuciones del ejemplo (I)
Salida Thread1 is alive Thread2 is alive El
código parece funcionar funcionar correctamente
16
Posibles ejecuciones del ejemplo (II)
Salida Thread1 Thread2 is alive is
alive Funcionara pero no de forma correcta al
intercalar las salidas de los threads.
17
Posibles ejecuciones del ejemplo (III)
El thread2 intenta escribir en un fichero
cerrado, falla el programa.
18
Flag de bloqueo de un objeto
  • El método synchronized permite controlar este
    flag para activar el acceso exclusivo al objeto.
  • Permitirá bloquear recursos compartidos para
    controlar el acceso de los threads sobre estos.
  • CriticalResource m_criticalResource
  • // bloquea el recurso antes de que sea usado
  • synchronized( m_criticalResource )
  • // uso el recurso
  • // fin del desbloqueo del recurso

19
Solución del ejemplo con synchronized
  • Aplicamos el método synchronized para intentar
    solucionar el problema
  • public void write( String s )
  • synchronized( m_file )
  • m_file.open( "filename.log" )
  • m_file.write( s )
  • m_file.close()

20
Posible ejecución del ejemplo con synchronized
Salida Thread1 Thread2 is alive is alive Aun se
puede producir esta situación
21
Solución final
  • Con el código proporcionado no hay manera evitar
    que se pueda dar la salida intercalada utilizando
    2 threads.
  • Modificaremos las instrucciones
  • m_log.write( m_threadID )
  • m_log.write( " is alive\n" )
  • Por una operación atómica de escritura
  • String logMessage m_threadID " is alive\n"
  • m_log.write( logMessage )

22
Problema de lectores/escritores
  • Base de datos accedida por una serie de procesos
    lectores y otros escritores que la modifican.
  • Los lectores pueden acceder de forma simultanea.
  • Los escritores deben hacerlo de forma individual
    y mientras modifiquen la base de datos esta no
    puede ser accedida por ningún lector.

23
Solución intuitiva 1 (I)
  • Object readLock new Object()
  • Object writeLock new Object()
  • int readers 0
  • public void read()
  • synchronized (readLock)
  • if ( readers 0 )
  • synchronized(writeLock)
  • ...

24
Solución intuitiva 1 (II)
  • Esta solución es incorrecta. Cuando salimos de la
    región synchronized (writelock), desaparece el
    bloqueo para los escritores.
  • Synchronized no es realmente un semáforo sino que
    sólo una región crítica .

25
Solución intuitiva 2 (I)
  • public void read()
  • synchronized (m_lock)
  • // lectura
  • public void write()
  • getDataToWrite()
  • synchronized(m_lock)
  • // escritura

26
Solución intuitiva 2 (II)
  • Esta solución funciona, aunque no hace
    exactamente lo que se esperaba de ella.
  • Protege correctamente las regiones críticas, pero
    no permite el acceso a varios lectores de forma
    simultanea a la base de datos, así que las
    ventajas del multithreading desaparecen.

27
Solución con espera activa (I)
  • public class CriticalResourceUsingSynchronized
  • private Object m_readLock new Object()
  • private int m_reading 0
  • public int read()
  • int readData 0
  • synchronized( m_readLock )
  • m_reading
  • // lectura
  • synchronized( m_readLock )
  • m_reading--
  • return readData

28
Solución con espera activa (II)
  • public void write ( int x )
  • boolean succeeded false
  • while ( !succeeded )
  • synchronized ( m_readLock )
  • if ( m_reading 0 )
  • // escritura
  • succeeded true
  • if ( succeeded false )
  • Thread.currentThread().yield(
    )

29
Comunicación entre threads
  • Las esperas activas no son eficientes y malgastan
    una serie de recursos inútilmente.
  • Existen dos métodos, wait() y notify() que
    permiten la comunicación entre threads.
  • Si un thread ejecuta la llamada wait() sobre un
    objeto x pausará su ejecución hasta que otro
    thread ejecute una llamada a notify() mediante el
    mismo objeto x.

30
Monitores (I)
  • La coordinación de threads que acceden a datos
    comunes puede resultar muy compleja. La
    información debe mantenerse en un estado
    consistente.
  • Los monitores mantienen un flujo de comunicación
    entre los threads

31
Monitores (II)
  • El esquema básico de los monitores es el
    siguiente
  • Object o new Object()
  • synchronized(o)
  • o.wait()
  • synchronized(o)
  • o.notify()

32
Monitores (III)
  • Los métodos wait y notify nos permiten
    implementar bloqueos reales en Java.
  • Para ello podemos utilizar la clase Lock, que
    implementa un semáforo booleano.

33
Clase Lock (I)
  • class Lock extends Object
  • private boolean m_bLocked false
  • public synchronized void lock()
  • if( m_bLocked )
  • do
  • try
  • wait()
  • catch( Exception e )

  • e.printStackTrace()
  • while ( m_bLocked )
  • m_bLocked true

34
Clase Lock (II)
  • public synchronized void releaseLock()
  • if( m_bLocked )
  • m_bLocked false
  • notify()
  • public synchronized boolean isLocked()
  • return m_bLocked

35
Solución con la clase Lock (I)
  • import Lock
  • public class CriticalResourceUsingLocks
  • private Lock m_readLock new Lock()
  • private int m_reading 0
  • private Lock m_writeLock new Lock()
  • public int read()
  • int readData 0
  • m_readLock.lock()
  • if( m_reading 0 )
  • m_writeLock.lock()
  • m_reading
  • m_readLock.releaseLock()

36
Solución con la clase Lock (II)
  • // lectura
  • m_readLock.lock()
  • m_reading--
  • if( m_reading 0 )
  • m_writeLock.releaseLock()
  • m_readLock.releaseLock()
  • return readData
  • public void write( int x )
  • m_writeLock.lock()
  • // escritura
  • m_writeLock.releaseLock()

37
Bibliografía
  • http//journal.iftech.com/articles/threadsync/
  • http//developer.java.sun.com
  • http//sunsite.dcc.uchile.cl/java
  • http//java.sun.com/docs/books/tutorial/index.html
Write a Comment
User Comments (0)
About PowerShow.com