75-62 Técnicas de Programación Concurrente II 2004 java Threads



Documentos relacionados
Threads. La plataforma JAVA soporta programas multhreading a través del lenguaje, de librerías y del sistema de ejecución. Dos.

MONITORES EN JAVA. Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Multitarea en Java. Rafa Caballero - UCM

Concurrencia. Primitivas IPC con bloqueo

PROGRAMACIÓN EN JAVA

Programación Java Curso C Draw

Programación Orientada a Eventos

Java: Programación Multithread

1 HILOS (THREADS) EN JAVA

I. Introducción a la programación orientada a objetos y al lenguaje JAVA Colegio Reuven Feuerstein Javier Navarro

Java nos ofrece la clase Thread y la interfaz Runable que permiten que varios procesos estén funcionando de forma concurrente.

Programación Concurrente en Java

TEMA 5: Control de la Concurrencia en Java (API Estándar)

Benemérita Universidad Autónoma del Estado de Puebla

Concurrencia en Android LSUB, GYSC, URJC

Object 1. Threads en Java

Concurrencia en Java

Introducción al lenguaje Java

Federico Peinado

Benemérita Universidad Autónoma del Estado de Puebla

Hebras y Sincronización en Java

Hilos en Java. Crear un Hilo. Detener un hilo. Fuente:

Identificadores, palabras reservadas, tipos de datos, operadores aritméticos y el sistema estándar de salida en Java

Concurrencia en Java

Introducción a la Programación Orientada a Objetos

class Nombre_Clase extends Nombre_SuperClase { cuerpo de la clase extendida }

UNIDAD III.- Programación Concurrente

Práctica 4: Java Remote Method Invocation (RMI)

Monitores Ing. Iván Medrano Valencia

Programación Concurrente en Java

CDI Exclusión mutua a nivel alto. conceptos

Modelo de Objetos Distribuidos

Facultad de Ingeniería Escuela de Ingeniería de Sistemas y Computación Algoritmia y Programación

Applets y Aplicaciones

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

Java y JVM: programación concurrente

Java: Clases Abstractas e Interfaces

GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C)

Práctica 1. Monitores en Java.

Programación concurrente en Java

void main(void) { string lname; list <string> lnamelist; cout << "Please enter your list of last names finishing with `.`"<<endl;

Concurrencia: deberes. Concurrencia: Exclusión Mutua y Sincronización. Concurrencia. Dificultades con la Concurrencia

Partes de un programa en Java. A. Ejemplo de un Programa en Java /* Programa Ejemplo de Java: Muestra una Ventana Archivo: Ejemplo1.

Arquitectura Cliente/Servidor. Invocación de Métodos Remotos RMI: Remote Method Invocation. Llamadas a Métodos Remotos

Curso de Java POO: Programación orientada a objetos

Programación Orientada a Objetos con Java

Para leer la entrada de consola, lo primero que se hace es construir un Scanner que este asociado al flujo de entrada estándar System.

Primer Parcial Septiembre 5 de 2009

dit UPM Tema 3: Concurrencia /ejercicios Análisis y diseño de software José A. Mañas

El lenguaje de programación Java

Programación Concurrente y Paralela. P(S) ; sección crítica P(S);

Programación Concurrente. Curso Java 2012, 2013 Juan Manuel Fernández Peña

Programación Orientada a Objetos en Java

3.9 Patrón Distributed callback

Manejo de eventos AWT

Repaso de las características más importantes de la programación Java y su adaptación a Android

2. Estructura de un programa en Java

Sistemas Operativos Práctica 4

Introducción a Java LSUB. 15 de enero de 2015 GSYC

Lo que necesitaremos para programar en Java, será un editor de texto o IDE y la JDK.

8. Sentencia return y métodos

Pontificia Universidad Católica de Chile Escuela de Ingeniería Departamento de Ciencia de la Computación. IIC1102 Introducción a la Programación

Tema 6. Reutilización de código. Programación Programación - Tema 6: Reutilización de código

Prof. Dr. Paul Bustamante

Java RMI. las RPC de Java. Parte I. Luis Fernando Llana Díaz. Departamento de Sistemas Informáticos y ProgramaciónUniversidad Complutense de Madrid

Creación de Applets Simples

1. Qué tipos de relación hay entre las siguientes clases?

Secretos de la Programación Concurrente

Modulo 1 El lenguaje Java

Sistemas Operativos. Curso 2016 Procesos

Aquí se declaran los. Aquí se declaran los métodos de la clase. *Atributos de la clase

JAVA: Applets. Diseño de aplicaciones web.

Programación Java. Práctica 11. Javier García de Jalón José Ignacio Rodríguez Alfonso Brazález Alberto Larzabal Jesús Calleja Jon García

Problema B Olonso y los laberintos

Java RMI Remote Method Invocation. Invocación Remota de Métodos en Java

Introducción... 1 Qué es Java?... 1 Compilando a Bytecode... 1 Usando jgrasp Para Hacer el Trabajo Sucio... 5 El Entorno de jgrasp...

ELO329: Diseño y Programación Orientados a Objetos 20 de Junio de Certamen Final

Manual del Usuario. Sistema de Help Desk

Estructuras de datos: Proyecto 2

MANUAL DE LA APLICACIÓN HELP DESK

Componentes Swing. Las clases cuyo nombre comienza por J forman parte de Swing. Todas las demás están incluidas en AWT (Abstract Window Toolkit)

Examen Septiembre Curso Programación en C++ Pág. 1

Java en 2 horas. Rodrigo Santamaría

Manual del Protocolo XML-RPC de Mensajería Negocios

Programación concurrente en Java. Breve introducción. Miguel Ángel LATRE Dept. de Informática e Ingeniería de Sistemas

Examen Junio- Grupo A Lunes 17 de Junio - Programación en C++ Pág. 1

Lenguajes de Programación Curso Práctica 4. Herencia. Utilización de interfaces y clases abstractas. 1. Interfaces Clases abstractas 2

Primera Escuela de la Red Temática SVO. Madrid, Noviembre, 2006 JAVA BÁSICO. Raúl Gutiérrez Sánchez LAEFF - INTA raul@laeff.inta.

Concurrencia: Exclusión mutua y Sincronización

1. Manejo de memoria estática 2. Manejo de memoria dinámica

Manual de Usuario UCMCompra

SOLUCION PARCIAL TASK SCHEDULER. Task Scheduler

PANEL DE CONTROL (Zona de Administración) MANUAL DE USO Por conexanet. Revisión 1.1 Fecha

Mesa de Ayuda Interna

Práctica 5: Common Object Request Broker Architecture CORBA

1. Introducción. 1.1 Ejercicio 1: Estación Meteorológica (4.0 pts.) Ejercicio 2: Gestión Académica: Alumnos (5.0 pts.)...

Tema 3: Herencia en C++ Programación Orientada a Objetos Curso 2008/2009 Begoña Moros Valle

Conceptos fundamentales de la POO. Fundamentos de la Programación Orientada a Objetos Objetos y Clases

Introducción a la programación orientada a objetos

Práctica 2: Java Remote Method Invocation (RMI)

Transcripción:

75-62 Técnicas de Programación Concurrente II 2004 java Threads FIUBA Ing. Osvaldo Clúa Bibliografía: tutorial de Java en http://java.sun.com Un buen libro (algo teórico) es Garg: Concurrent and Distributed Computing in Java Puede haber material que ayude en las páginas de sus clases en http: Se presupone un conocimiento general de Java. En Internet hay bastantes cursos para poder seguir. En la página Web de la materia se dejó una colección de guías de estudio que se usó en años anteriores. Threads Para crear un thread en Java existen dos opciones: Extender la clase Thread. Implementar la interface Runnable. La elección de alguna de estas opciones depende del diseño general. Al no admitir Java herencia múltiple, la implementación de interfaces sirve para denotar propiedades secundarias al eje de herencia. El siguiente es un ejemplo de estas dos formas de hacerlo: 1. /** 2. * Primero.java 3. * 4. * El HolaMundo de las threads 5. */ 6. 7. class T1 extends Thread 8. { 9. public void run() { 10. System.out.println 11. ("Hola, soy tu primer Thread, extendi la clase Thread "+ 12. Thread.currentThread()); 13. } 14. } 15. class T2 implements Runnable 16. { 17. public void run() { 18. System.out.println 19. ("Hola, soy tu primer Thread, implemente Runnable " + 20. Thread.currentThread());

21. } 22. } 23. 24. public class Primero 25. { 26. public static void main(string args[]) { 27. T1 t1 = new T1(); 28. T2 ru = new T2(); 29. t1.start(); 30. Thread t2 = new Thread (ru); 31. t2.start(); 32. System.out.println("Hola, soy el Thread principal"+ 33. Thread.currentThread()); 34. try{ 35. t1.join(); 36. t2.join(); 37. } 38. catch(interruptedexception e){ 39. e.printstacktrace(); 40. System.exit(0); 41. } 42. System.out.println("Chau, solo queda el Thread principal"+ 43. Thread.currentThread()); 44. } 45. } En el código anterior se ven las dos formas de crear un thread. Al llamar al método start() de Thread se crea efectivamente el Thread y se le da control al método run() que es el que hay que programar. En el caso de implementar runnable se debe crear el thread para que haya acceso a este método. En la clase Thread están definios los métodos start() y join() con el significado habitual. La salida de este programa se ve así: 1.Hola, soy tu primer Thread, extendi la clase Thread Thread[Thread-0,5,main] 2.Hola, soy el Thread principalthread[main,5,main] 3.Hola, soy tu primer Thread, implemente Runnable Thread[Thread-1,5,main] 4.Chau, solo queda el Thread principalthread [main,5,main] -2-

Donde: Thread-0, Thread-1 y principalthread son los nombres de los threads. 5 es la prioridad y main es el grupo al que pertenecen. Estados de un thread: Un thread Java puede estar en uno de cuatro estados posibles: New. Cuando el objeto se crea (usando la isntrucción new()). Runnable. Una vez llamado el método start(). Blocked. Cuando se está a la espera de una operación de I/O o se llamó a los métodos sleep(), suspend() (este último está desaprobado y se quitará de alguna versión posterior de Java) Dead.. Cuando se terminó el run(...) o se llamó a stop() (también desaprobado). Como ejemplo mas completo se propone un conjunto de dos contadores sobre un mismo canvas: 1. /* El contador */ 2. import java.awt.*; 3. 4. public class Cont implements Runnable 5. { 6. long cont=0;int adormir; 7. Color color; 8. 9. Cont(int tiempo, Color c){ 10. color=c; adormir=tiempo; 11. } 12.public void run() { 13. while (true){ 14. try {Thread.sleep(aDormir);} 15. catch (InterruptedException e) {} 16. cont++; 17. } -3-

18. } 19.public void paint(graphics g) { 20. g.setcolor(color); 21. g.setfont(new Font (null,font.plain,24)); 22. g.drawstring( String.valueOf(cont), 10, 30); 23. } 24.} Este contador duerme según un parámetro de construcción (tiempo) y se incrementa en uno. Además tiene la responsabilidad de dibujarse en paint. Una aplicación usa de este contador, creando uno distinto en un canvas que divide en dos graphics: 1. /* La aplicacion del contador */ 2. import java.awt.*; 3. import java.awt.event.*; 4. 5. class ContAp extends Frame implements Runnable{ 6. Thread tic,tac,anima; 7. Cont c1,c2; 8. Canvas c; 9. int ancho=200,alto=300; 10.ContAp(String s){ 11. super(s); 12. c1=new Cont(500,Color.black); 13. c2=new Cont(1000,Color.blue); 14. tic=new Thread(c1);tac=new Thread(c2); 15. c=new Canvas (); 16. c.setsize(ancho,alto); 17. add(c); pack(); setvisible(true); 18. tic.start();tac.start(); 19. addwindowlistener(new WindowAdapter() 20. {public void windowclosing(windowevent e) {System.exit(0);}}); 21. anima=new Thread(this);anima.start(); 22. repaint(); 23. } 24.public void paint (Graphics g){ 25. Graphics cg=c.getgraphics(); 26. cg.setcolor(color.light_gray); 27. cg.fillrect(0,0,ancho,alto); 28. Graphics g1=cg.create(0,0,ancho,alto/2);c1.paint (g1); -4-

29. Graphics g2=cg.create(0,alto/2,ancho,alto/2); c2.paint(g2); 30. } 31.public void run() { 32. while (true) { 33. try {Thread.sleep(250);} 34. catch (InterruptedException e) {} 35. repaint(); 36. } 37. } 38. 39.} En el método paint se ve como divide el graphic en dos y le pide a cada contador que lo dibuje. Falta una clase principal que tenga el método public static void main(string s[]) para completar el ejemplo. Se usaron 3 threads: tick, tack y anima. Las dos primeras son de cada contador en tanto que la última es el thread necesario para la animación. Pruebe sin ella a ver que pasa. En el caso anterior cada elemento tiene su contexto gráfico propio. El ejemplo de los puntos adjunto a esta práctica muestra una variación compartiendo un único canvas. Como último ejemplo simple, se analizará la aplicación de puntos que rebotan en un canvas. Acá los puntos son una clase cuya responsabilidad es dibujarse, mantener su posición y velocidad. La clase PunCan contiene al canvas, la inicialización y el método paint() para dibujarse. En este caso se usó una técnica de animación conocida como Double Buffer. en la clase PunCan se hizo override de update: public void update(graphics g){paint(g);} Evitando que se borre la ventana con cada llamado. Se definió: Graphics migr; Image miim; -5-

Para tener donde trabajar offscreen. La image se crea del mismo tamaño que el canvas: miim=createimage((new Double(ca.getBounds().getWidth ())).intvalue(),(new Double(ca.getBounds().getHeight ())).intvalue()); migr=miim.getgraphics(); Y de esta imagen se crea un nuevo contexto gráfico. Se dibuja sobre este contexto gráfico y se envía toda la imagen al canvas de la pantalla en un solo paso: for(int i=0;i<cant;i++) {p[i].paint(migr);} Graphics g1=ca.getgraphics(); g1.drawimage(miim,0,0,this); } Esto anula el flicker. Es importante que entienda como cambiar la velocidad de animación. Sincronización El siguiente es el código de un productor consumidor "automático" para su uso desde la consola de texto: 1. /** 2. * Buffer.java Con primitivas de sincronizacion 3. */ 4. 5. public class Buffer 6. { 7. private static final int BUFFER_SIZE = 5; 8. private int cant; // items en el buffer 9. private int in; // Proximo libre 10. private int out; // Proximo lleno 11. private Object[] buffer; 13. public Buffer() 14. { 15. cant = 0; // Comienza Vacio 16. in = 0; 17. out = 0; 18. buffer = new Object[BUFFER_SIZE]; 19. } 21. public synchronized void poner(object item) { 22. while (cant == BUFFER_SIZE) { 23. try {wait();} -6-

24. catch (InterruptedException e) { } 25. } 26. ++cant; //Agrega al buffer 27. buffer[in] = item; 28. in = (in + 1) % BUFFER_SIZE; 29. if (cant == BUFFER_SIZE) 30. System.out.println("Entro " + item + 31. " Buffer LLENO"); 32. else 33. System.out.println("Entro " + item + 34. " Buffer Size = " + cant); 35. notify(); // despierta algun consumidor 36. } 37. public synchronized Object sacar() { 38. Object item; 39. while (cant == 0) { 40. try {wait(); } 41. catch (InterruptedException e) { } 42. } 43. --cant; 44. item = buffer[out]; 45. out = (out + 1) % BUFFER_SIZE; 46. if (cant == 0) 47. System.out.println("Salio " + item + " Buffer VACIO"); 48. else 49. System.out.println("Salio " + item + 50. " Buffer Size = " + cant); 51. notify(); 52. return item; 53. } 54. } Este buffer es el objeto encargado de hacer la sincronización entre el productor y el consumidor. No es un objeto activo (No tiene threads). En Java cada objeto tiene un lock (monitor es el meta-lenguaje de Java). Al ejecutar un método synchronized se toma este monitor y se lo libera al terminar la ejecución del método. Solo un thread puede tener el monitor de un objeto. El lazo de sincronización está en el uso de: wait() que libera el monitor del objeto y suspende al thread que lo llama hasta que ocurra una interrupción. notify() que provoca una interrupción a algún thread que espera por el monitor del objeto. notifyall() que provoca una interrupción en todos los threads que esperan por el monitor del objeto. Como pueden interrumpirse (y salir del wait( )) por otras causas, se hace el while -7-

por la condición de las líneas 23 y 40. El productor es: 1. /** 2. * Productor.java 3. */ 5. import java.util.*; 7. public class Productor extends Thread 8. { 9. private Buffer buffer; 10. final static int NAP_TIME=5; 11. public Productor(Buffer b) {buffer = b;} 12. public void run() 13. { 14. Date mens; 15. while (true){ 16. dormir();mens = new Date(); 17. System.out.println("Producido " + mens); 18. buffer.poner(mens); 19. } 20. } 21. public static void dormir() { // para suspenderse 22. int sleeptime = (int) (NAP_TIME * Math.random () ); 23. try { Thread.sleep(sleepTime*1000); } 24. catch(interruptedexception e) { } 25. } 26. } y el consumidor 1. /** 2. * Consumidor.java 3. */ 5. import java.util.*; 7. public class Consumidor extends Thread 8. { 9. private Buffer buffer; 10. final static int NAP_TIME=5; 11. public Consumidor(Buffer b) 12. {buffer = b;} 13. -8-

14. public void run() 15. {Date mens; 16. while (true){ 17. dormir(); 18. System.out.println("Consumidor quiere consumir."); 19. mens = (Date)buffer.sacar(); 20. } 21. } 22. public static void dormir() { // para suspenderse 23. int sleeptime = (int) (NAP_TIME * Math.random() ); 24. try { Thread.sleep(sleepTime*1000); } 25. catch(interruptedexception e) { } 26. } 27. } Para su ejecución hace falta una clase como la que sigue: 1. /** * Prubuf.java */ 4. public class Prubuf 5. { 6. public static void main(string args[]) { 7. Buffer sr = new Buffer(); 8. Productor pt = new Productor(sr); 9. Consumidor ct = new Consumidor(sr); 10. pt.start(); ct.start(); 11. } 12. } En el archivo zip correspondiente a esta guía encontrará un productor-consumidor con interface gráfica como la que sigue. El código sin embargo no hace uso de un thread continuo como el primer código. Ejercicios: 1. Resolver el Productor Consumidor con un thread para cada uno mas los threads necesarios para la interface gráfica. 2. Generalizarlo para "n" productores y "k" consumidores (a ingresar desde la interface). 3. Resolver con una interface gráfica parecida el problema de los Fumadores. 4. Haga un programa que permita hacer Drag & Drop de una forma simple a través de un canvas. Use las clases asociadas a Java2D para determinar los límites y dibujar las formas (no hay threads). 5. Programe un juego simple con una víbora que se mueve en la pantalla. Ud dispone de una palmeta (rectángulo) para aplastarle la cabeza. Si no lo logra, una marca de la palmeta queda en la pantalla y la víbora debe esquivarla. -9-