![Page 1: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/1.jpg)
dit UPM
Algunos derechos reservados. Este documento se distribuye bajo licencia Crea9ve Commons Reconocimiento-‐NoComercial-‐Compar9rIgual 3.0 Unported. hBp://crea9vecommons.org/licenses/by-‐nc-‐sa/3.0/deed.es
Programación concurrente — Mecanismos de sincronización de bajo nivelJuan Antonio de la Puente <[email protected]>
20141009
![Page 2: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/2.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Referencias
•ScoB Oaks & Henry WongJava Threads O'Reilly Media; 3rd ed (2004) !
•Kathy Sierra & Bert Bates Head First Java, ch. 15O'Reilly Media; 2nd ed (2005)
2
![Page 3: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/3.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Mecanismos de sincronización de bajo nivel
• Con monitores se pueden construir programas concurrentes correctos para todo 9po de situaciones
• A veces se usan otros mecanismos de sincronización de menor nivel de abstracción -‐ por razones de costumbre o de eficiencia
‣ semáforos ‣ cerrojos explícitos ‣ variables de condición
• Son digciles de usar correctamente y pueden dar lugar a problemas complicados
3
![Page 4: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/4.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Semáforos
• Un semáforo es un objeto que 9ene un valor entero no nega9vo
• Su valor sólo se puede alterar mediante dos operaciones atómicas ‣ adquirir: decrementa el valor del semáforo -‐ si es 0, la hebra que lo invoca se suspende
‣ liberar: incrementa el valor del semáforo -‐ si hay hebras esperando, con9núa una de ellas ✓ el valor del semáforo no se modifica
• Es un mecanismo elemental de sincronización ‣ interés histórico: inventado por Edsger Dijkstra hacia 1965
4
![Page 5: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/5.jpg)
© 2014 Juan A. de la PuenteProgramación concurrente — Mecanismos de bajo nivel
java.u2l.concurrent.Semaphore
public class Semaphore … { !/* constructor */ public Semaphore(int permits); /* adquirir */ public void acquire() throws InterruptedException; !/* liberar */ public void release(); … }
5
![Page 6: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/6.jpg)
© 2014 Juan A. de la PuenteProgramación concurrente — Mecanismos de bajo nivel
Exclusión mutua con semáforosSemaphore mutex = new Semaphore(1); !// thread 1 // thread 2 … mutex.acquire(); mutex.acquire(); // región crítica // región crítica mutex.release(); mutex.release(); …
6
• El valor inicial indica que se dispone de 1 permiso para acceder a un recurso (por ejemplo, variable compar9da)
• No pude haber más de una hebra en su región crí9ca
![Page 7: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/7.jpg)
© 2014 Juan A. de la PuenteProgramación concurrente — Mecanismos de bajo nivel
Productor-‐consumidor con semáforospublic class Buffer<E> { ! private E almacen; Semaphore mutex = new Semaphore(1); // exclusión mutua Semaphore sitio = new Semaphore(1); // sitio para 1 dato Semaphore datos = new Semaphore(0); // no hay datos en buffer ! public void enviar(E dato) throws InterruptedException { sitio.acquire(); // espera que haya sitio mutex.acquire(); // acceso exclusivo al almacén almacen = dato; mutex.release(); // libera acceso exclusivo datos.release(); // avisa de que hay datos disponibles } ! public E recibir() throws InterruptedException { E dato = null; datos.acquire(); // espera que haya datos mutex.acquire(); // acceso exclusivo al almacén dato = almacen; mutex.release(); // libera acceso exclusivo sitio.release(); // avisa de que hay sitio return dato; } }
7
![Page 8: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/8.jpg)
© 2014 Juan A. de la PuenteProgramación concurrente — Mecanismos de bajo nivel
Comentarios
•Más complicado de usar y entender
• Es fácil cometer errores. ‣ acquire() sin release(); ‣ orden incorrecto ‣muchos errores, digciles de detectar
• En general, es mejor usar métodos sincronizados
8
public void enviar(E dato) … { mutex.acquire(); sitio.acquire(); almacen = dato; datos.release(); mutex.release();
} !public E recibir() ... { … mutex.acquire(); datos.acquire(); dato = almacen; sitio.release(); mutex.release(); ...
}
Ejemplo
¿por qué es incorrecto?
![Page 9: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/9.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Cerrojos explícitos
• Como los que se usan de forma implícita en synchronized ‣ y otras formas con propiedades algo diferentes
• Se definen en java.u2ls.concurrent.locks !
!
!
!
• Varias implementaciones ‣ ReentrantLock, etc.
9
public interface Lock { void lock(); // bloquea el cerrojo void unlock(); // desbloquea la RC ... }
![Page 10: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/10.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Condiciones
• Permiten la sincronización mediante condiciones explícitas
• Se definen en !
!
!
!
• Varias implementaciones en java.u2l.concurrent.locks • Digcil de usar, mejor usar notify() y notifyAll()
10
public interface Condition { void await() // libera cerrojo y espera throws InterruptedException; void signal(); // desbloquea un thread void signalAll(); // desbloquea todos }
![Page 11: Programación concurrente: mecanismos de sincronización de bajo nivel](https://reader037.vdocuments.mx/reader037/viewer/2022100602/558e692e1a28ab0f668b4591/html5/thumbnails/11.jpg)
Programación concurrente — Mecanismos de bajo nivel © 2014 Juan A. de la Puente
Resumen
• A veces se usan mecanismos de sincronización con un nivel de abstracción menor que los monitores ‣ semáforos ‣ cerrojos ‣ variables de condición !
• Razones históricas o código heredado ‣ todo se puede hacer con monitores ‣mayor nivel de abstracción, menos errores
11