1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads...

26
1 TEMA 2. TEMA 2. Programación Programación Concurrente Concurrente 1. 1. Introducción Introducción 2. 2. Primer ejemplo y estado de los Primer ejemplo y estado de los threads threads 3. 3. Grupos de Threads y planificación Grupos de Threads y planificación interna. interna. 4. 4. Concurrencia. Concurrencia. 5. 5. El problema del productor/consumidor El problema del productor/consumidor 6. 6. El problema de los lectores y El problema de los lectores y escritores. escritores. 7. 7. Aplicaciones. Aplicaciones.

Transcript of 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads...

Page 1: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

11

TEMA 2.TEMA 2.Programación ConcurrenteProgramación Concurrente

1.1. IntroducciónIntroducción

2.2. Primer ejemplo y estado de los threadsPrimer ejemplo y estado de los threads

3.3. Grupos de Threads y planificación Grupos de Threads y planificación interna.interna.

4.4. Concurrencia.Concurrencia.

5.5. El problema del productor/consumidorEl problema del productor/consumidor

6.6. El problema de los lectores y El problema de los lectores y escritores.escritores.

7.7. Aplicaciones.Aplicaciones.

Page 2: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

22

BibliografíaBibliografía

Bishop,J. Java. Bishop,J. Java. Fundamentos de Fundamentos de programación. Capítulo 13. programación. Capítulo 13.

Bobadilla, J. y otros. Comunicaciones y Bobadilla, J. y otros. Comunicaciones y Bases de Datos en Java. Capítulo 2.Bases de Datos en Java. Capítulo 2.

Doug Lea. Programación Concurrente Doug Lea. Programación Concurrente en Java.en Java.

Page 3: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

33

La habilidad de un programa individual La habilidad de un programa individual de hacer más de una cosa a la vez es de hacer más de una cosa a la vez es implementado normalmente a través implementado normalmente a través de lo que se conoce como threads de lo que se conoce como threads (hilos, hebras o procesos java).(hilos, hebras o procesos java).

Una hebra puede definirse de forma Una hebra puede definirse de forma intuitiva como un trozo de ejecución intuitiva como un trozo de ejecución del programa que tienen lugar del programa que tienen lugar simultáneamente con, e simultáneamente con, e independientemente, de cualquier otra independientemente, de cualquier otra cosa que se esté ejecutando.cosa que se esté ejecutando.

1 . Introducción

Page 4: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

44

Intuitivamente debemos Intuitivamente debemos distinguir entre la multitarea de distinguir entre la multitarea de un sistema operativo y la un sistema operativo y la programación en threads.programación en threads.

Los entornos que permiten el uso Los entornos que permiten el uso de threads permiten la exclusión de threads permiten la exclusión mutua en recursos compartidos mutua en recursos compartidos mediante la sincronización. mediante la sincronización.

Se debe tener mucho cuidado con Se debe tener mucho cuidado con el abrazo mortal (el abrazo mortal (deadlockdeadlock).).

1 . Introducción

Page 5: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

55

La elección exacta de qué parte del La elección exacta de qué parte del sistema debe ser sincronizada es la parte sistema debe ser sincronizada es la parte más delicada de la programación más delicada de la programación concurrente.concurrente.

La JVM no es un proceso ejecutable, es La JVM no es un proceso ejecutable, es una especificación. Un programa que una especificación. Un programa que implementa la especificación es lo que se implementa la especificación es lo que se conoce como conoce como java runtimejava runtime (JRE). (JRE).

Las aplicaciones Java y los applets son Las aplicaciones Java y los applets son threads por sí.threads por sí.

La forma en que se implementa threads La forma en que se implementa threads en Java es mediante la clase en Java es mediante la clase java.lang.Threadjava.lang.Thread que implementa la que implementa la interface interface runnablerunnable..

1 . Introducción

Page 6: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

66

public class Printer extends Thread public class Printer extends Thread {{

public void run() {public void run() {

for (int b = -128; b < 128; b++) {for (int b = -128; b < 128; b++) {

System.out.println(b);System.out.println(b);

}}}}}}

2. Primer ejemplo

Page 7: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

77

public class Printer implements public class Printer implements Runnable {Runnable {

public void run() {public void run() {

for (int b = -128; b < 128; b++) for (int b = -128; b < 128; b++) {{

System.out.println(b);System.out.println(b);

}}}}}}

2 . Primer ejemplo

Page 8: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

88

En el primer caso se crearía una instancia de la forma En el primer caso se crearía una instancia de la forma habitualhabitual

Printer p=new Printer();Printer p=new Printer();

y en el segundo:y en el segundo:

Printer p=new Printer();Printer p=new Printer();Thread proc =new Thread(p); Thread proc =new Thread(p);

Aunque el objeto de tipo Aunque el objeto de tipo RunnableRunnable contiene la lógica contiene la lógica principal, la clase principal, la clase ThreadThread es la única que encapsula el es la única que encapsula el mecanismo para lanzar y controlar el thread. mecanismo para lanzar y controlar el thread.

Para lanzar a ejecución un hilo debemos utilizar el Para lanzar a ejecución un hilo debemos utilizar el método método startstart((), que invocará al método ), que invocará al método runrun().().

2. Primer ejemplo

Page 9: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

99

Esquemáticamente, la vida de un Esquemáticamente, la vida de un Thread se corresponde con el Thread se corresponde con el siguiente gráfico: siguiente gráfico:

2 . Primer ejemplo

Estados

NEW

RUNNABLE

NOT RUNNABLE

DEAD

Page 10: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1010

Para cada uno de los casos:Para cada uno de los casos:

public class ThreadTest {public class ThreadTest {

public static void main(String args[]) {public static void main(String args[]) {Printer bp = new Printer();Printer bp = new Printer();bp.start();bp.start();for (int i = -128; i < 128; i++) {for (int i = -128; i < 128; i++) {System.out.println("Metodo main: " + i);System.out.println("Metodo main: " + i);

} }}} }}

2 . Primer ejemplo

Page 11: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1111

Para cada uno de los casos:Para cada uno de los casos:

public class ThreadTest {public class ThreadTest {public static void main(String args[]) {public static void main(String args[]) {Printer r= new Printer();Printer r= new Printer();Thread bp = new Thread(r);Thread bp = new Thread(r);bp.start();bp.start();for (int i = -128; i < 128; i++) {for (int i = -128; i < 128; i++) {System.out.println("Metodo main: " + i);System.out.println("Metodo main: " + i);

}}}}}}

2 . Primer ejemplo

Page 12: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1212

Es conveniente darle a cada thread un nombre Es conveniente darle a cada thread un nombre distinto. Para identificarlos se le suele pasar un distinto. Para identificarlos se le suele pasar un StringString al constructor (sino, el sistema lo nombra al constructor (sino, el sistema lo nombra internamente como Thread-N) que me sirva para internamente como Thread-N) que me sirva para identificarlo.identificarlo.

public class MultiThreadTest {public class MultiThreadTest {public static void main(String args[]) {public static void main(String args[]) {

Printer bp1 = new Printer("bp1");Printer bp1 = new Printer("bp1");Printer bp2 = new Printer("bp2");Printer bp2 = new Printer("bp2");Printer bp3 = new Printer("bp3");Printer bp3 = new Printer("bp3");bp1.start();bp1.start();bp2.start();bp2.start();bp3.start();bp3.start();

}}}}

2 . Primer ejemplo

Page 13: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1313

public class Printer extends Thread {public class Printer extends Thread {

public Printer(String s) {public Printer(String s) {

super(s);super(s);

}}

public void run() {public void run() {

for (int b = -128; b < 128; b++) {for (int b = -128; b < 128; b++) {System.out.println(getName() + ": " + b);System.out.println(getName() + ": " + b);

}}}}}}

2 . Primer ejemplo

Page 14: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1414

A veces es conveniente darle más importancia a unos A veces es conveniente darle más importancia a unos sobre otrossobre otros

public class TestPrioridad {public class TestPrioridad {public static void main(String args[]) {public static void main(String args[]) {

Printer bp1 = new Printer("Pepe");Printer bp1 = new Printer("Pepe");Printer bp2 = new Printer("Maria");Printer bp2 = new Printer("Maria");Printer bp3 = new Printer("Juan");Printer bp3 = new Printer("Juan");bp1.setPriority(Thread.MIN_PRIORITY);bp1.setPriority(Thread.MIN_PRIORITY);bp2.setPriority(Thread.NORM_PRIORITY);bp2.setPriority(Thread.NORM_PRIORITY);bp3.setPriority(Thread.MAX_PRIORITY);bp3.setPriority(Thread.MAX_PRIORITY);bp1.start();bp1.start();bp2.start();bp2.start();bp3.start();bp3.start();

}}}}

3 . Planificación interna

Page 15: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1515

La Java Virtual Machine utiliza un La Java Virtual Machine utiliza un algoritmo reentrante, pero no round-algoritmo reentrante, pero no round-robin.robin.

A veces interesa ralentizar un thread, A veces interesa ralentizar un thread, dormirlo.dormirlo.

try {sleep(1000);}try {sleep(1000);}

catch (InterruptedException e) {catch (InterruptedException e) {}}

3 . Planificación interna

Page 16: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1616

Hay muchas veces que los threads deben Hay muchas veces que los threads deben de comunicarse y sincronizarse. de comunicarse y sincronizarse.

La comunicación permite que la ejecución La comunicación permite que la ejecución de hilo influya en la ejecución de otro de hilo influya en la ejecución de otro mediante el intercambio de datos.mediante el intercambio de datos.

La sincronización permite establecer La sincronización permite establecer restricciones sobre el orden de ejecución restricciones sobre el orden de ejecución entre diferentes hilos.entre diferentes hilos.

4 . Concurrencia

Page 17: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1717

La sincronización limita el acceso a un método u objeto de La sincronización limita el acceso a un método u objeto de un thread cada vez. Para sincronizar los objetos o métodos un thread cada vez. Para sincronizar los objetos o métodos se añade la palabra reservada se añade la palabra reservada synchronizedsynchronized, después del , después del modificador de acceso.modificador de acceso.

De esta forma se accede en exclusión mutua al objeto o al De esta forma se accede en exclusión mutua al objeto o al método.método.

synchronized void metodo();synchronized void metodo();

En Java se sigue el mismo mecanismo que describió En Java se sigue el mismo mecanismo que describió HoareHoare, pero con una variación: se sincronizan los métodos , pero con una variación: se sincronizan los métodos mediante una palabra reservada, no mediante el uso mediante una palabra reservada, no mediante el uso explícito de un monitor. explícito de un monitor.

Todo objeto en Java tiene asociado un monitor implícito.Todo objeto en Java tiene asociado un monitor implícito.

4 . Concurrencia

Page 18: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1818

public class Printer {public class Printer {

static int i = 0;static int i = 0;

public public synchronizedsynchronized void print() { void print() {

for (i = 1; i <= 10; i++) {for (i = 1; i <= 10; i++) {

System.out.println(i);System.out.println(i);

}}}}}}

4 . Concurrencia

Page 19: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

1919

Debemos tener alguna forma que bajo algunas Debemos tener alguna forma que bajo algunas condiciones nos permita bloquear el condiciones nos permita bloquear el ThreadThread hasta que el hasta que el recurso que necesite se encuentre libre. La forma de hacer recurso que necesite se encuentre libre. La forma de hacer esto es mediante el uso de las instrucciones esto es mediante el uso de las instrucciones wait()wait() y y notify()notify(). . try {try { // ejecutar el código// ejecutar el código wait();wait();} catch (InterruptedException e){} catch (InterruptedException e){}}

Tanto el Tanto el wait() wait() como el como el notify()notify() se deben invocar desde se deben invocar desde métodos métodos synchronizedsynchronized, ya que sólo se pueden invocar si el , ya que sólo se pueden invocar si el threadthread en cuestión posee el monitor del objeto, cosa que en cuestión posee el monitor del objeto, cosa que sólo ocurre si accede a un método sólo ocurre si accede a un método synchronizedsynchronized. Hay que . Hay que tener en cuenta que al hacer un tener en cuenta que al hacer un wait()wait() se liberan todos los se liberan todos los recursos, incluyendo el monitor.recursos, incluyendo el monitor.

En cuanto al En cuanto al notify()notify(), puede ocurrir que cuando es , puede ocurrir que cuando es invocado haya en la cola cero o más invocado haya en la cola cero o más threadsthreads esperando. esperando.

4 . Concurrencia

Page 20: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2020

class Almacen {class Almacen { private int seq; private int seq; private boolean disponible = false;private boolean disponible = false;

public synchronized int consumir() {public synchronized int consumir() { while (disponible == false) {while (disponible == false) { try {try { wait();wait(); } }

catch (InterruptedException e) {}catch (InterruptedException e) {} }} disponible = false;disponible = false; notify();notify(); return seq;return seq; }}

5 . Problema del productor consumidor

Almacen

Page 21: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2121

public synchronized void producir(int value) public synchronized void producir(int value) {{

while (disponible == true) {while (disponible == true) { try {try { wait();}wait();} catch (InterruptedException e){}catch (InterruptedException e){} }}

seq = value;seq = value; disponible = true;disponible = true; notify();notify(); }}}}

5 . Problema del productor consumidor

Almacen

Page 22: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2222

class Productor extends Thread {class Productor extends Thread {private Almacen almacen;private Almacen almacen;private int numero;private int numero;public Productor(Almacen c, int numero) {public Productor(Almacen c, int numero) {

almacen = c;almacen = c;this.numero = numero;}this.numero = numero;}

public void run() {public void run() { for (int i = 0; i <= 10; i++) {for (int i = 0; i <= 10; i++) { almacen.producir(i);almacen.producir(i); System.out.println("Productor #" + this.numero + System.out.println("Productor #" + this.numero +

" pon: " + i);" pon: " + i); try {try {

sleep((int)(Math.random() * 100));}sleep((int)(Math.random() * 100));} catch (InterruptedException e) {}}}}catch (InterruptedException e) {}}}}

5 . Problema del productor consumidor

Productor

Page 23: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2323

class Consumidor extends Thread {class Consumidor extends Thread {private Almacen almacen;private Almacen almacen;private int numero;private int numero;public Consumidor(Almacen c, int numero) {public Consumidor(Almacen c, int numero) {

almacen = c;almacen = c;this.numero = numero;this.numero = numero;

}}public void run() {public void run() {

int value = 0;int value = 0;for (int i = 0; i <= 10; i++) {for (int i = 0; i <= 10; i++) { value = almacen.consumir();value = almacen.consumir(); System.out.println("Consumidor #" +System.out.println("Consumidor #" +

this.numero + " cons: " +value);}}}this.numero + " cons: " +value);}}}

5 . Problema del productor consumidor

Consumidor

Page 24: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2424

class ProdConTest {class ProdConTest {public static void main(String args[]) {public static void main(String args[]) {

Almacen c = new Almacen();Almacen c = new Almacen();Productor p1 = new Productor(c, 1);Productor p1 = new Productor(c, 1);Consumidor c1 = new Consumidor(c, Consumidor c1 = new Consumidor(c,

1);1);p1.start();p1.start();c1.start();c1.start();

}}}}

5 . Problema del productor consumidor

Principal

Page 25: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2525

““El problema de los lectores y El problema de los lectores y escritores es una abstracción del escritores es una abstracción del acceso a una base de datos, donde acceso a una base de datos, donde varios procesos pueden leer pero la varios procesos pueden leer pero la escritura debe de hacerse en escritura debe de hacerse en exclusión mutua.”exclusión mutua.”

Su resolución esta en un fichero aparte.Su resolución esta en un fichero aparte.

6 . Problema de lectores y escritores

Lectores/ Escritores

Page 26: 1 TEMA 2. Programación Concurrente 1.Introducción 2.Primer ejemplo y estado de los threads 3.Grupos de Threads y planificación interna. 4. Concurrencia.

2626

Servicios WebServicios Web: la mayoría de los servicios basados en sockets. : la mayoría de los servicios basados en sockets. Demonios de http (cliente y servidor). Motores de servlets. Demonios de http (cliente y servidor). Motores de servlets. Servidores de aplicaciones.Servidores de aplicaciones.

Cálculo NuméricoCálculo Numérico: tratan de maximizar el rendimiento haciendo : tratan de maximizar el rendimiento haciendo uso del paralelismo.uso del paralelismo.

Procesamiento de entrada/salidaProcesamiento de entrada/salida: los programas concurrentes : los programas concurrentes pueden utilizar los tiempos de espera perdidos en operaciones pueden utilizar los tiempos de espera perdidos en operaciones lentas de entrada/salida y , por lo tanto hacer un uso más lentas de entrada/salida y , por lo tanto hacer un uso más eficiente de los recursos del sistema.eficiente de los recursos del sistema.

Simulación:Simulación: estimación de productividad de un sistema y video estimación de productividad de un sistema y video juegos.juegos.

Aplicaciones basadas en IGUAplicaciones basadas en IGU: la concurrencia permite el uso de : la concurrencia permite el uso de controles incluso en acciones que consumen mucho tiempo.controles incluso en acciones que consumen mucho tiempo.

7 . Aplicaciones

Aplicaciones