Capitulos de este wiki
  1. 1 DECLARACIÓN DE INTENCIONES
  2. 2 PRESENTACIÓN
  3. 3 INTRODUCCIÓN A JAVA
  4. 4 Origen de JAVA
  5. 5 Características de JAVA
  6. 6 HotJava
  7. 7 JAVA para aplicaciones corporativas
  8. 8 INSTALACIÓN DEL JDK
  9. 9 Windows
  10. 10 Solaris
  11. 11 Linux
  12. 12 Compilación sin JDK
  13. 13 CONCEPTOS BÁSICOS DE JAVA
  14. 14 Programación en JAVA
  15. 15 Control del Flujo
  16. 16 Clases
  17. 17 Variables y Métodos de Instancia
  18. 18 Alcance de Objetos y Reciclado de Memoria
  19. 19 Herencia
  20. 20 Control de Acceso
  21. 21 Variables y Métodos Estaticos
  22. 23 Clases Abstractas
  23. 24 Interfaces
  24. 25 Métodos Nativos
  25. 26 Paquetes
  26. 27 Referencias
  27. 28 Punteros y Referencias C
  28. 29 Referencias en Java
  29. 30 Referencias y Arrays
  30. 31 Referencias y Listas
  31. 32 Punteros C/C++ y Referencias Java
  32. 33 PROGRAMAS BÁSICOS EN JAVA
  33. 34 Una mínima aplicación en Java
  34. 35 Compilación y Ejecución de HolaMundo
  35. 36 El visor de Applets de Sun (appletviewer)
  36. 37 Arquitectura de appletviewer
  37. 38 Métodos de appletviewer
  38. 39 Funciones de menú de appletviewer
  39. 40 Un Applet basico en Java
  40. 41 Compilación de un Applet
  41. 42 La marca APPLET de html
  42. 43 Atributos de APPLET
  43. 44 Paso de parametros a Applets
  44. 45 Tokens en parametros de llamada
  45. 46 El parametro ARCHIVE
  46. 47 Depuración general
  47. 48 Ciclo de vida de un Applet
  48. 49 Protección de Applets
  49. 50 Escribir Applets Java
  50. 51 La aplicación Fecha (Aproximación a OOP)
  51. 52 EL DEPURADOR DE JAVA - JDB
  52. 54 La clase Math
  53. 55 La clase Character
  54. 56 La clase Float
  55. 57 La clase Double
  56. 58 La clase Integer
  57. 59 La clase Long
  58. 60 La clase Boolean
  59. 61 La clase String
  60. 62 La clase StringBuffer
  61. 63 Uso de Conversiones
  62. 64 ABSTRACT WINDOW TOOLKIT (AWT)
  63. 65 Interface de Usuario
  64. 66 Estructura del AWT
  65. 67 Componentes y Contenedores
  66. 68 Tipos de Componentes
  67. 69 BorderLayout
  68. 70 CardLayout
  69. 71 CheckboxGroup
  70. 72 Color
  71. 73 Component
  72. 74 Button - Botones
  73. 75 Canvas
  74. 76 Checkbox
  75. 77 Choice
  76. 78 Container
  77. 79 Label - Etiquetas
  78. 80 List - Listas
  79. 81 Scrollbar - Barras de desplazamiento
  80. 82 TextComponent
  81. 83 Fijar el tamaño preferido
  82. 84 La clase Event
  83. 85 FlowLayout
  84. 86 Cambio de fuente de caracteres
  85. 87 GridLayout
  86. 88 GridBagLayout
  87. 89 Uso de Insets
  88. 90 MenuComponent
  89. 91 LayoutManager
  90. 92 Diseño de Componentes propios
  91. 93 Creación de Aplicaciones con AWT
  92. 94 Crear el Marco de la aplicación (Frame)
  93. 95 Inicializar Fuentes, Colores, Layouts y demas recursos
  94. 96 Crear menús y Barras de Menús
  95. 97 Crear los controles, dialogos, ventanas, etc.
  96. 98 Layouts
  97. 99 FlowLayout
  98. 100 BorderLayout
  99. 101 GridLayout
  100. 102 GridBagLayout
  101. 103 CardLayout
  102. 104 Crear un Layout propio
  103. 105 Control de Eventos
  104. 106 La clase Event
  105. 107 Tipos de Eventos
  106. 108 Generación y Propagación de Eventos
  107. 109 Métodos de Control de Eventos
  108. 110 Action_Event
  109. 111 Mejorar el Diseño de Interfaces
  110. 112 Cambio de Font de Caracteres
  111. 113 Colores de Fondo y Texto
  112. 114 Fijar el Tamaño Preferido
  113. 115 Uso de Insets
  114. 116 Habilitar y Deshabilitar Componentes
  115. 117 Botón Grafico
  116. 118 GRÁFICOS
  117. 119 Métodos para Dibujos
  118. 120 Líneas
  119. 121 Rectangulos
  120. 122 Círculos, Elipses
  121. 123 EXCEPCIONES EN JAVA
  122. 124 Funciones Graficas
  123. 125 Manejo de Excepciones
  124. 126 Fractales
  125. 127 Generar Excepciones en Java
  126. 128 Líneas Flotantes
  127. 129 Excepciones Predefinidas
  128. 130 Métodos para Imagenes
  129. 131 Crear Excepciones Propias
  130. 132 Doble Buffering de Graficos
  131. 133 Capturar Excepciones
  132. 134 Nuevas Clases para Dibujo
  133. 135 Propagación de Excepciones
  134. 136 La Clase MediaTracker
  135. 137 THREADS Y MULTITHREADING
  136. 138 Sonido en Java
  137. 139 Flujo en Programas
  138. 140 Entrada por Ratón
  139. 141 Creación y Control de Threads
  140. 142 Arrancar y Parar Threads
  141. 143 Suspender y Reanudar Threads
  142. 144 Estados de un Thread
  143. 145 Scheduling
  144. 146 Prioridades, demonios...
  145. 147 Ejemplo de Animación
  146. 148 Comunicación entre Threads
  147. 149 MÉTODOS NATIVOS
  148. 150 Escribir Código Java
  149. 151 Compilar el Código Java
  150. 152 Crear el fichero de Cabecera
  151. 153 Crear el fichero de Stubs
  152. 154 Escribir la función C
  153. 155 Crear la Librería Dinamica
  154. 156 Ejecutar el Programa
  155. 157 ENTRADA / SALIDA ESTÁNDAR
  156. 158 La clase System
  157. 159 Clases comunes de Entrada/Salida
  158. 160 FICHEROS EN JAVA
  159. 161 Ficheros
  160. 162 Streams de Entrada
  161. 163 Streams de Salida
  162. 164 Ficheros de Acceso Aleatorio
  163. 165 COMUNICACIONES EN JAVA
  164. 166 Comunicaciones en Unix
  165. 167 Sockets
  166. 168 Diferencias entre Sockets Stream y Datagrama
  167. 169 Uso de Sockets
  168. 170 Dominios de Comunicaciones
  169. 171 Modelo de Comunicaciones con Java
  170. 172 Apertura de Sockets
  171. 173 Creación de Streams
  172. 174 Cierre de Sockets
  173. 175 Mínimo Cliente SMTP
  174. 176 Servidor de Eco
  175. 177 Cliente/Servidor TCP/IP
  176. 178 Servidor Simple de HTTP
  177. 179 Red en Windows '95 (sin conexión)
  178. 180 Clases Útiles en Comunicaciones
  179. 181 ARQUITECTURA MVC EN JAVA
  180. 182 La Arquitectura MVC
  181. 183 Observador y Observable
  182. 184 Cómo utilizar Observer y Observable
  183. 185 Ejemplo de aplicación MVC
  184. 186 APLICACIONES EN JAVA
  185. 187 Etiqueta
  186. 188 Reloj Digital
  187. 189 Persiana
  188. 190 Solapas
  189. 191 Transparencia
  190. 192 Calculadora
  191. 193 Cuenta-Kilómetros
  192. 194 Cartel
  193. 195 FINAL Y AGRADECIMIENTOS
  194. 196 JAVA Y MATLAB
Temas relacionados:
Búsquedas relacionadas:
  • Java tutorial
  • Programas java
  • Tutorial bat
  • Tutorial subversion
  • Tutorial artmoney
  • Programas en java
  • Tutorial word xp
  • Tutorial netcat

    Tutorial de Java - Comunicación entre Threads

    148 - Comunicación entre Threads


    Tutorial creado por Agustín Froufe . Extraido de: http://www.publispain.com/supertutoriales/
    08 Mayo 2007
    ""

    Otra clave para el éxito y la ventaja de la utilización de múltiples threads en una aplicación, o aplicación multithreaded, es que pueden comunicarse entre sí. Se pueden diseñar threads para utilizar objetos comunes, que cada thread puede manipular independientemente de los otros threads.


    El ejemplo clásico de comunicación de threads es un modelo productor/consumidor. Un thread produce una salida, que otro thread usa (consume), sea lo que sea esa salida. Vamos entonces a crear un productor, que será un thread que irá sacando caracteres por su salida; crearemos también un consumidor que ira recogiendo los caracteres que vaya sacando el productor y un monitor que controlará el proceso de sincronización entre los threads. Funcionará como una tubería, insertando el productor caracteres en un extremos y leyéndolos el consumidor en el otro, con el monitor siendo la propia tubería.



    Comunicacin entre Threads

    Productor

    El productor extenderá la clase Thread, y su código es el siguiente:

    class Productor extends Thread {
    private Tuberia tuberia;
    private String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public Productor( Tuberia t ) {
    // Mantiene una copia propia del objeto compartido
    tuberia = t;
    }

    public void run() {
    char c;

    // Mete 10 letras en la tubería
    for( int i=0; i < 10; i++ )
    {
    c = alfabeto.charAt( (int)(Math.random()*26 ) );
    tuberia.lanzar( c );
    // Imprime un registro con lo añadido
    System.out.println( "Lanzado "+c+" a la tuberia." );
    // Espera un poco antes de añadir más letras
    try {
    sleep( (int)(Math.random() * 100 ) );
    } catch( InterruptedException e ) {
    ;
    }
    }
    }
    }

    Notar que creamos una instancia de la clase Tuberia, y que se utiliza el método tuberia.lanzar() para que se vaya construyendo la tubería, en principio de 10 caracteres.

    Consumidor

    Veamos ahora el código del consumidor, que también extenderá la clase Thread:

    class Consumidor extends Thread {
    private Tuberia tuberia;

    public Consumidor( Tuberia t ) {
    // Mantiene una copia propia del objeto compartido
    tuberia = t;
    }

    public void run() {
    char c;

    // Consume 10 letras de la tubería
    for( int i=0; i < 10; i++ )
    {
    c = tuberia.recoger();
    // Imprime las letras retiradas
    System.out.println( "Recogido el caracter "+c );
    // Espera un poco antes de coger más letras
    try {
    sleep( (int)(Math.random() * 2000 ) );
    } catch( InterruptedException e ) {
    ;
    }
    }
    }
    }

    En este caso, como en el del productor, contamos con un método en la clase Tuberia, tuberia.recoger(), para manejar la información.

    Monitor

    Una vez vistos el productor de la información y el consumidor, nos queda por ver qué es lo que hace la clase Tuberia.


    Lo que realiza la clase Tuberia, es una función de supervisión de las transacciones entre los dos threads, el productor y el consumidor. Los monitores, en general, son piezas muy importantes de las aplicaciones multithreaded, porque mantienen el flujo de comunicación entre los threads.

    class Tuberia {
    private char buffer[] = new char[6];
    private int siguiente = 0;
    // Flags para saber el estado del buffer
    private boolean estaLlena = false;
    private boolean estaVacia = true;

    // Método para retirar letras del buffer
    public synchronized char recoger() {
    // No se puede consumir si el buffer está vacío
    while( estaVacia == true )
    {
    try {
    wait(); // Se sale cuando estaVacia cambia a false
    } catch( InterruptedException e ) {
    ;
    }
    }
    // Decrementa la cuenta, ya que va a consumir una letra
    siguiente--;
    // Comprueba si se retiró la última letra
    if( siguiente == 0 )
    estaVacia = true;
    // El buffer no puede estar lleno, porque acabamos de consumir
    estaLlena = false;
    notify();

    // Devuelve la letra al thread consumidor
    return( buffer[siguiente] );
    }

    // Método para añadir letras al buffer
    public synchronized void lanzar( char c ) {
    // Espera hasta que haya sitio para otra letra
    while( estaLlena == true )
    {
    try {
    wait(); // Se sale cuando estaLlena cambia a false
    } catch( InterruptedException e ) {
    ;
    }
    }
    // Añade una letra en el primer lugar disponible
    buffer[siguiente] = c;
    // Cambia al siguiente lugar disponible
    siguiente++;
    // Comprueba si el buffer está lleno
    if( siguiente == 6 )
    estaLlena = true;
    estaVacia = false;
    notify();
    }
    }

    En la clase Tuberia vemos dos características importantes: los miembros dato (buffer[]) son privados, y los métodos de acceso (lanzar() y recoger()) son sincronizados.


    Aquí vemos que la variable estaVacia es un semáforo, como los de toda la vida. La naturaleza privada de los datos evita que el productor y el consumidor accedan directamente a éstos. Si se permitiese el acceso directo de ambos threads a los datos, se podrían producir problemas; por ejemplo, si el consumidor intenta retirar datos de un buffer vacío, obtendrá excepciones innecesarias, o se bloqueará el proceso.


    Los métodos sincronizados de acceso impiden que los productores y consumidores corrompan un objeto compartido. Mientras el productor está añadiendo una letra a la tubería, el consumidor no la puede retirar y viceversa. Esta sincronización es vital para mantener la integridad de cualquier objeto compartido. No sería lo mismo sincronizar la clase en vez de los métodos, porque esto significaría que nadie puede acceder a las variables de la clase en paralelo, mientras que al sincronizar los métodos, sí pueden acceder a todas las variables que están fuera de los métodos que pertenecen a la clase.


    Se pueden sincronizar incluso variables, para realizar alguna acción determinada sobre ellas, por ejemplo:

    sincronized( p ) {
    // aquí se colocaría el código
    // los threads que estén intentando acceder a p se pararán
    // y generarán una InterruptedException
    }

    El método notify() al final de cada método de acceso avisa a cualquier proceso que esté esperando por el objeto, entonces el proceso que ha estado esperando intentará acceder de nuevo al objeto. En el método wait() hacemos que el thread se quede a la espera de que le llegue un notify(), ya sea enviado por el thread o por el sistema.


    Ahora que ya tenemos un productor, un consumidor y un objeto compartido, necesitamos una aplicación que arranque los threads y que consiga que todos hablen con el mismo objeto que están compartiendo. Esto es lo que hace el siguiente trozo de código, del fuente TubTest.java:

    class TubTest {
    public static void main( String args[] ) {
    Tuberia t = new Tuberia();
    Productor p = new Productor( t );
    Consumidor c = new Consumidor( t );

    p.start();
    c.start();
    }
    }

    Compilando y ejecutando esta aplicación, podremos observar nuestro modelo el pleno funcionamiento.


    Monitorización del Productor


    Los programas productor/consumidor a menudo emplean monitorización remota, que permite al consumidor observar el thread del productor interaccionando con un usuario o con otra parte del sistema. Por ejemplo, en una red, un grupo de threads productores podrían trabajar cada uno en una workstation. Los productores imprimirían documentos, almacenando una entrada en un registro (log). Un consumidor (o múltiples consumidores) podría procesar el registro y realizar durante la noche un informe de la actividad de impresión del día anterior.


    Otro ejemplo, a pequeña escala podría ser el uso de varias ventanas en una workstation. Una ventana se puede usar para la entrada de información (el productor), y otra ventana reaccionaría a esa información (el consumidor).


    Peer, es un observador general del sistema.

    ""

    Autor y licencia de 'Tutorial de Java'


    Tutorial de Agustín Froufe . Extraido de: http://www.publispain.com/supertutoriales/ CopyLeft
    Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.