{
  "version": "2",
  "formats": {
    "markdown": {
      "content": "## Page 1\n\nUnidad 1\nProgramación concurrente\n\nTema 3 Dependencias de estados\n\n&lt;page_number&gt;1&lt;/page_number&gt;\n\n---\n\n\n## Page 2\n\n# Contenidos\n\n1.  Dependencias de estado\n2.  Cómo enfrentarse a fallos\n    *   Excepciones\n    *   Cancelación\n3.  Métodos protegidos\n    *   Suspensión protegida\n    *   Funcionamiento del monitor\n    *   Esperas con protección y notificaciones\n    *   Más tipos de esperas y notificaciones\n    *   Uso de bibliotecas\n4.  Patrones de diseño concurrentes\n    *   Productor – Consumidor\n    *   Bloqueo de lectura y escritura\n5.  Bibliografía\n\n&lt;page_number&gt;2&lt;/page_number&gt;\n\n---\n\n\n## Page 3\n\n# Dependencias de estado\n\n*   Para realizar cualquier acción (ej: tomar nota de un mensaje telefónico) se precisa dos condiciones:\n    *   **Externas**: un objeto recibe un mensaje que solicita la realización de la acción\n    *   **Internas**: el objeto se encuentra en el estado adecuado para realizar la acción\n*   Las técnicas de **exclusión** preservan los **invariantes del objeto** ... el control de concurrencia **dependiente del estado** impone problemas adicionales relativos a las **precondiciones y postcondiciones**\n*   Las acciones pueden tener precondicones que no siempre se cumplen y postcondiciones que no siempre se pueden alcanzar\n\n<table>\n  <tr>\n    <td>Suena el teléfono</td>\n    <td>Tengo bolígrafo</td>\n    <td>No tengo bolígrafo</td>\n  </tr>\n  <tr>\n    <td>Tomar el mensaje</td>\n    <td>Responder al teléfono</td>\n    <td>Responder al teléfono</td>\n  </tr>\n  <tr>\n    <td></td>\n    <td>Escribir el mensaje</td>\n    <td>????</td>\n  </tr>\n</table>\n\n&lt;page_number&gt;3&lt;/page_number&gt;\n\n---\n\n\n## Page 4\n\n# Dependencias de estado\n\n*   En un sistema ideal todos los métodos carecen de precondiciones basadas en su estado y siempre satisfacen sus postcondiciones\n    *   No siempre se pueden definir acciones no dependientes del estado\n*   Dos estrategias de diseño\n    1. Optimista imposición vivacidad\n        *   Los métodos de tipo probar y ver siempre nos permiten probar cuando se invocan, pero no siempre tienen éxito, por tanto, pueden tener que enfrentarse a fallos\n        *   Se basan en la existencia de excepciones y otros mecanismos que indican el momento en el que no se satisfacen las postcondiciones\n\n&lt;page_number&gt;4&lt;/page_number&gt;\n\n---\n\n\n## Page 5\n\n# Dependencias de estado\n\n## Dos estrategias de diseño\n\n### 2. Conservador imposición seguridad\n\n- Los métodos del tipo **comprobar** y **actuar** se niegan a seguir adelante salvo que se cumplan las precondiciones. Cuando las precondiciones son válidas las acciones siempre tienen éxito\n- Se basan en estructuras de protección que garantizan cuando son válidas las precondiciones y seguirán siendo válidas durante el transcurso de la acción\n\n* La combinación de ambas estrategias es posible y frecuente\n* Las acciones dependientes del estado requieren un esfuerzo y atención en la programación concurrente\n\n&lt;page_number&gt;5&lt;/page_number&gt;\n\n---\n\n\n## Page 6\n\n# Cómo enfrentarse a fallos\n\n*   La necesidad de estrategias probar y ver suelen surgir cuando no se quiere\\* o no se puede probar las **precondiciones**\n*   No existen estructuras para definir la comprobación\n    *   Probar que un cerrojo se mantiene activado\n*   Precondiciones con ámbito temporal (restricciones de activación)\n    *   Sistema de archivos que tiene espacio cuando entra en el método pero cuando escribe se queda sin espacio\n*   Condiciones que cambian por señales procedentes de otros hilos\n    *   Cancelación en modo asíncrono\n*   Condiciones muy costosas computacionalmente\\*\n    *   Comprobar que una matriz esté normalizada en forma triangular superior\n\n&lt;page_number&gt;6&lt;/page_number&gt;\n\n---\n\n\n## Page 7\n\n# Cómo enfrentarse a fallos\n## Excepciones\n\n*   La concurrencia introduce la posibilidad de que falle cierta parte del programa mientras otras siguen adelante\n*   Los métodos pueden lanzar excepciones cuando han detectado que sus **postcondiciones** no pueden llevarse a efecto (fallo)\n*   Las acciones fallidas tienen seis posibles respuestas:\n    *   Finalización súbita -NullPointerException-\n    *   Continuación -Notificación fallida listener animación-\n    *   Vuelta atrás -Falta de interferencia con otros hilos-\n    *   Avance o recuperación -Alcanzar un punto seguro-\n    *   Reintentos\n    *   Manejadores\n\n&lt;page_number&gt;7&lt;/page_number&gt;\n\n---\n\n\n## Page 8\n\n# Cómo enfrentarse a fallos\n## Excepciones\n\n*   Reintentos\n    *   Pueden consumir cantidades ilimitadas de CPU\n        -   Soluciones\n            1.  Limitar el número de intentos\n            2.  Añadir retardos temporales en el tiempo\n\n```java\nclass ClientUsingSocket { // Code sketch\n    int portnumber = 1234;\n    String server = \"gee\";\n    // ...\n    Socket retryUntilConnected() throws InterruptedException {\n        // first delay is randomly chosen between 5 and 10secs\n        long delayTime = 5000 + (long) (Math.random() * 5000);\n        for (;;) {\n            try {\n                return new Socket(server, portnumber);\n            } catch (IOException ex) {\n                Thread.sleep(delayTime);\n                delayTime = delayTime * 3 / 2 + 1; // increase 50%\n            }\n        }\n    }\n}\n```\n\n&lt;img&gt;Blue V icon&lt;/img&gt; &lt;img&gt;Green circle with white checkmark icon&lt;/img&gt;\n&lt;page_number&gt;8&lt;/page_number&gt;\n\n---\n\n\n## Page 9\n\n# Cómo enfrentarse a fallos\n## Excepciones\n\n*   **Manejadores**\n    *   Se puede delegar las operaciones de tratamiento de errores en **manejadores centralizados**\n    *   El manejador puede realizar acciones de compensación en otros hilos del sistema\n        *   Difícil de realizar sin el control centralizado\n    *   El código es más extensible y flexible cuando lo usan clientes que no saben como responder a fallos\n    *   Se puede sustituir excepciones por retrollamadas, eventos otras técnicas de notificación\n        *   Tener cuidado cuando las notificaciones escapen el control de flujo basado en pila que proporcionan las excepciones\n\n&lt;page_number&gt;9&lt;/page_number&gt;\n\n---\n\n\n## Page 10\n\n# Cómo enfrentarse a fallos\n## Excepciones\n\n*   Manejadores\n\n```mermaid\nclassDiagram\n    class <<interface>> ManejadorDeExcepcionServicio {\n        +manejar(e:ExcepcionDeServicio)\n    }\n    class <<interface>> ServidorConExcepcion {\n        +servicio() throws ExcepcionDeServicio\n    }\n    class <<Proxy>> ServidorManejado {\n        +servicio()\n    }\n    class <<Sujeto Real>> ServidorImpl {\n        +servicio()\n    }\n    ManejadorDeExcepcionServicio <|-- ManejadorImpl\n    ServidorConExcepcion <|-- ServidorManejado\n    ServidorManejado \"1\" -- \"1\" ServidorImpl : servidor\n```\n\n```java\nclass ServidorManejado implements ServidorConExcepcion {\n    final ServidorConExcepcion servidor = new ServidorImpl();\n    final ManejadorDeExcepcionServicio manejador = new ManejadorImpl();\n\n    public void servicio() { // sin sentencia throw\n        try {\n            servidor.servicio();\n        } catch (ExcepcionDeServicio e) {\n            manejador.manejar(e);\n        }\n    }\n}\n```\n\n&lt;img&gt;Blue V icon&lt;/img&gt; &lt;img&gt;Green checkmark icon&lt;/img&gt;\n&lt;page_number&gt;10&lt;/page_number&gt;\n\n---\n\n\n## Page 11\n\n# Cómo enfrentarse a fallos\n## Cancelaciones\n\n*   Cuando las actividades de un hilo experimentan un fallo o cambian de rumbo puede ser necesario cancelar actividades de otros hilos independientemente de lo que estén haciendo\n*   Las solicitudes de cancelación introducen situaciones de fallo inherentemente impredecibles para los hilos que se están ejecutando\n*   La naturaleza de la cancelación es asíncrona\n\nLos programas concurrentes tienen la obligación adicional de asegurar un estado coherente de los objetos internos que participen en varios hilos\n\n&lt;page_number&gt;11&lt;/page_number&gt;\n\n---\n\n\n## Page 12\n\n# Cómo enfrentarse a fallos\n## Cancelaciones\n\n*   La cancelación es un fenómeno natural en la mayoría de programas multihilos\n*   Actividades asociadas al botón Cancelar de un GUI\n*   Terminación de bucles de animación en actividades multimedia\n*   Hilos que producen resultados que no se necesitan\n*   Conjunto de actividades que no pueden proseguir porque una o más han encontrado errores o excepciones inesperadas\n\n&lt;page_number&gt;12&lt;/page_number&gt;\n\n---\n\n\n## Page 13\n\n# Cómo enfrentarse a fallos\n## Cancelaciones\n\n*   Interrupción\n    *   La técnica mejor soportada para abordar la cancelación se basa en el estado de interrupción de los hilos\n        *   Se configura mediante `Thread.interrupt()`\n            *   No impone una terminación inmediata permite que el hilo interrumpido pueda hacer operaciones de limpieza\n        *   Se inspecciona mediante `Thread.isInterrupted()`\n        *   Se borra mediante `Thread.interrupted()`\n        *   Se responde en algunas ocasiones lanzando una `InterruptedException`\n    *   Las interrupciones de hilos sirven como solicitudes de cancelación de actividades\n    *   La carencia de interrupciones se puede utilizar como precondición que se comprobará en los puntos seguros\n\n&lt;page_number&gt;13&lt;/page_number&gt;\n\n---\n\n\n## Page 14\n\n# Cómo enfrentarse a fallos\n## Cancelaciones\n\n*   Interrupción\n    *   Las comprobaciones de interrupción se realizan automáticamente dentro `Object.wait()`\n        Thread.join() Thread.sleep()\n    *   Finalizan cuando se produce la interrupción lanzando InterruptedException\n    *   Permite a los hilos despertar y aplicar el código de cancelación\n*   Existen dos situaciones en las que los hilos no pueden comprobar el estado de las interrupciones o recibir InterruptedException\n    *   En bloqueos de cierres sincronizados\n    *   En operaciones de E/S\n\n&lt;page_number&gt;14&lt;/page_number&gt;\n\n---\n\n\n## Page 15\n\n# Métodos protegidos\n\n*   Los métodos conservadores del tipo **comprobar y actuar** no realizan ciertas operaciones si no se cumplen sus **precondiciones**\n*   Tipos de acciones en caso de no cumplimiento de las precondiciones:\n    *   **Rechazo**\n        *   Lanzar una excepción si no se cumplen las precondiciones\n    *   **Suspensión protegida** – no tiene analogía en programas secuenciales-\n        *   Suspender la invocación actual del método hasta que se cumpla la precondición\n    *   **Plazos temporales** – no tiene analogía en programas secuenciales-\n        *   Se establece una cota temporal de espera hasta que la precondición pase a ser verdadera\n\n&lt;page_number&gt;15&lt;/page_number&gt;\n\n---\n\n\n## Page 16\n\n# Métodos protegidos\n## Suspensión con protección\n\n*   Contexto del problema\n    *   Contador limitado\n\n```java\ninterface ContadorLimitado {\n    static final long MIN = 0; // mínimo valor permitido\n    static final long MAX = 10; // máximo valor permitido\n\n    long getValor(); // INV: MIN <= getValor() <= MAX\n    // INIT: getValor() == MIN\n    void inc(); // PRE: getValor() < MAX\n    void dec(); // PRE: getValor() > MIN\n}\n```\n\n&lt;img&gt;Blue V icon&lt;/img&gt; &lt;img&gt;Green circle with white checkmark icon&lt;/img&gt;\n&lt;page_number&gt;16&lt;/page_number&gt;\n\n---\n\n\n## Page 17\n\n# Métodos protegidos\n## Suspensión con protección\n\n*   Definición de estados lógicos\n    *   Conjunto de estados limitados para proteger las acciones\n\n<table>\n  <thead>\n    <tr>\n      <th>Estado</th>\n      <th>Condición</th>\n      <th>inc()</th>\n      <th>dec()</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td><b>superior</b></td>\n      <td>getValor() == MAX</td>\n      <td>no</td>\n      <td>sí</td>\n    </tr>\n    <tr>\n      <td><b>medio</b></td>\n      <td>MIN &lt; getValor() &lt;MAX</td>\n      <td>sí</td>\n      <td>sí</td>\n    </tr>\n    <tr>\n      <td><b>inferior</b></td>\n      <td>getValor() == MIN</td>\n      <td>sí</td>\n      <td>no</td>\n    </tr>\n  </tbody>\n</table>\n\n<mermaid>\ngraph LR\n    A[Superior] -->|Dec desde MAX| B[Medio]\n    B -->|Dec a MIN| C[Inferior]\n    C -->|Inc desde MIN| B\n    B -->|Inc a MAX| A\n</mermaid>\n\n&lt;page_number&gt;17&lt;/page_number&gt;\n\n---\n\n\n## Page 18\n\n# Métodos protegidos\n## Suspensión con protección\n\n*   **Definición de estados lógicos**\n    *   Muchos objetos que mantienen atributos que, en su conjunto, constituyen un espacio de estados muy grande, pero solamente mantienen un pequeño espacio lógico de estados para proteger sus acciones\n*   Es preciso tener cuidado a la hora de caracterizar estos estados\n    *   Si MAX es igual a MIN+1 no existe estado intermedio\n    *   Si MAX es igual a MIN no hay forma de distinguir el estado Superior del Inferior.\n*   **Representación** de los estados lógicos\n    *   Mediante una variable de rol, representando cada estado distinto mediante un nuevo valor.\n    *   Objetos como estados PD Estado\n\n&lt;page_number&gt;18&lt;/page_number&gt;\n\n---\n\n\n## Page 19\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n*   Las implementaciones de la suspensión con protección:\n    *   Usan los métodos `Object.wait()`, `Object.notify()`, `Object.notifyAll()`\n    *   Se basan en la siguiente estrategia\n        *   Para cada condición que sea preciso esperar se escribe un **bucle wait()** protegido que da lugar a que el hilo actual se bloquee si la condición de protección es falsa\n        *   Se asegura que todos los métodos que dan lugar a cambio de estado que afecten al valor de cualquier condición de espera, **notificarán (notify())** el cambio de estado para que los hilos despierten y vuelvan a comprobar condición de protección\n    *   El método `wait()` hace que el thread actual espere hasta que otro thread se lo notifique (`notify()`) o cambie una condición\n\n&lt;page_number&gt;19&lt;/page_number&gt;\n\n---\n\n\n## Page 20\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n*   Las entidades que poseen tanto **cerrojos** como **conjuntos de espera** se denominan **monitores**\n*   La clase `java.lang.Object` puede servir de monitor\n    *   Tiene un **cerrojo** (`synchronized`)\n    *   Tiene un **conjunto de espera** que manipula mediante\n        -   `wait`, `notify`, `notifyAll`, `Thread.interrupt`\n*   Los métodos `wait`, `notify`, `notifyAll` solamente se pueden invocar cuando el objeto haya adquirido el **manejo de la sincronización**\n    *   `IllegalMonitorStateException`\n\n&lt;page_number&gt;20&lt;/page_number&gt;\n\n---\n\n\n## Page 21\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n*   **Acciones asociadas a wait y notify**\n\n    *   `wait()`\n        *   La JVM pone el hilo en el conjunto de espera interno asociado al objeto en cuestión (recurso)\n        *   Se libera el cerrojo de sincronización correspondiente al objeto en cuestión (recurso), se mantienen todos los demás cerrojos que haya adquirido el hilo\n\n    *   `wait(long milisegundos)` Esperas temporizadas\n        *   Admite un argumento que especifica el tiempo máximo deseado de permanencia en el conjunto de espera\n        *   Funciona del mismo modo que la versión no temporizada salvo que, si no se ha notificado una espera antes de concluir sus límites de tiempo, la liberación se produce automáticamente\n\n&lt;page_number&gt;21&lt;/page_number&gt;\n\n---\n\n\n## Page 22\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n*   `notify()`\n    *   Si existe algún hilo en estado de espera interno asociado al objeto cerrojo, la JVM saca del conjunto de espera un hilo arbitrario, digamos **T**\n        *   Si existen varios hilos en el conjunto de espera no existe una garantía de conocer cual de los hilos se elige\n    *   **T** pasa a un estado de listo, debe obtener el cerrojo de sincronización y esperará.\n        *   **T** no pasará a un estado en ejecución hasta que el hilo que llama a `notify()` no libera el cerrojo\n    *   **T** reanuda desde el punto siguiente a su `wait()`\n\n&lt;page_number&gt;22&lt;/page_number&gt;\n\n---\n\n\n## Page 23\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n**notifyAll()**\n* Su funcionamiento es similar a notify()\n* Saca todos los hilos que se encuentren en conjunto de espera\n\n**Thread.interrupt()**\n* Su funcionamiento es similar a notify() para un hilo que esté suspendido en un wait, salvo que, una vez vuelto a adquirir el cerrojo el método lanza una InterruptedException y actualiza el valor del estado de interrupción del hilo a false\n\n&lt;page_number&gt;23&lt;/page_number&gt;\n\n---\n\n\n## Page 24\n\n# Métodos protegidos\n\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n*   Ejemplo para explicar la mecánica subyacente de `wait` `notify`\n*   Ejemplo inútil desde el punto de vista funcional\n*   Analizar un posible resultado de ejecución cuando existen tres hilos( T1, T2, T3 ) que invocan a métodos pertenecientes a un cierto objeto x de tipo X común\n\n```java\npublic class X{\n    public synchronized void w() throws InterruptedException{\n        antes(); wait(); despues();\n    }\n    public synchronized void n(){\n        notifyAll();\n    }\n    protected void antes(){}\n    protected void despues(){}\n}\n```\n\n&lt;img&gt;V logo&lt;/img&gt;\n&lt;page_number&gt;24&lt;/page_number&gt;\n\n---\n\n\n## Page 25\n\n# Métodos protegidos\n## Funcionamiento del monitor (C.A.R. Hoare en 1974)\n\n<mermaid>\ngraph TD\n    subgraph Theads\n        T1[T1]\n        T2[T2]\n        T3[T3]\n    end\n\n    subgraph Tiempo\n        direction LR\n        A[ ] -- \" \" --> B[ ]\n        B[ ] -- \"0\" --> C[ ]\n        C[ ] -- \"1\" --> D[ ]\n        D[ ] -- \"2\" --> E[ ]\n        E[ ] -- \"3\" --> F[ ]\n        F[ ] -- \"4\" --> G[ ]\n        G[ ] -- \"5\" --> H[ ]\n        H[ ] -- \"6\" --> I[ ]\n        I[ ] -- \"7\" --> J[ ]\n        J[ ] -- \"8\" --> K[ ]\n        K[ ] -- \"9\" --> L[ ]\n        L[ ] -- \"10\" --> M[ ]\n        M[ ] -- \" \" --> N[ ]\n    end\n\n    subgraph Threads\n        TW1[T1]\n        TW2[T2]\n        TW3[T3]\n    end\n\n    TW1 --> T1\n    TW2 --> T2\n    TW3 --> T3\n\n    subgraph Monitor\n        M1[begin x.w()]\n        M2[adquirir cerrojo]\n        M3[antes()]\n        M4[wait:]\n        M5[liberar cerrojo]\n    end\n\n    subgraph Thread 1\n        T1A[begin x.w() <br> adquirir cerroj <br> antes() <br> wait: <br> liberar cerrojo <br> entrar en conjunto <br> de espera]\n    end\n\n    subgraph Thread 2\n        T2A[begin x.w() <br> adquirir cerroj <br> antes() <br> wait: <br> liberar cerrojo <br> entrar en conjunto <br> de espera]\n    end\n\n    subgraph Thread 3\n        T3A[begin x.n() <br> esperar bloqueo <br> adquirir cerrojo < br> notifyAll(); <br> liberar cerrojo]\n    end\n\n        T1A --> M1\n        T1A -- \" \" --> T2A\n        T1B --> M1\n    end\n\n    subgraph Monitor\n        M6[salir del conjunto <br> de espera <br> esperar bloqueo]\n        M7[adquirir cerrojo <br> despues() <br> liberar cerrojo]\n    end\n\n    T1B --> M6\n    T2B --> M6\n\n    subgraph Thread 1\n        T1B[salir del conjunto <br> de espera <br> esperar bloqueo <br> adquirir cerrojo <br> despues() <br> liberar cerrojo]\n    end\n\n    subgraph Monitor\n        M8[adquirir cerroj <br> despue: <br> liberac]\n    end\n\n        T1B --> M8\n        T2B --> M8\n\n    subgraph Thread 2\n        T2C[adquirir <br> despues() <br> liberar]\n    end\n\n    T2B --> T2C\n    T2C --> M8\n\nend\n\nDoug Lea. Programación concurrente en Java: Principios y patrones de diseño. 2ª ed. PEARSON EDUCACION, 2000. Pag. 192\n&lt;page_number&gt;25&lt;/page_number&gt;\n\n---\n\n\n## Page 26\n\n# Métodos protegidos\n## Esperas con protección y notificaciones\n\n```java\nclass CountadorLimitadoSimple {\n\n    static final long MIN = 0; // mínimo valor permitido\n    static final long MAX = 10; // máximo valor permitido\n\n    protected long valor = MIN;\n\n    public synchronized long getValor() {\n        return valor;\n    }\n\n    public synchronized void inc() throws InterruptedException {\n        esperarSalirEstadoSuperior();\n        setValor(valor + 1);\n    }\n\n    protected void esperarSalirEstadoSuperior() throws InterruptedException {\n        while (valor == MAX)\n            wait();\n    }\n}\n```\n\n<table>\n<thead>\n<tr>\n<th>Estado</th>\n<th>Condición</th>\n<th>inc()</th>\n<th>dec()</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>superior</td>\n<td>getValor() == MAX</td>\n<td>no</td>\n<td>sí</td>\n</tr>\n<tr>\n<td>medio</td>\n<td>MIN &lt; getValor() &lt;MAX</td>\n<td>sí</td>\n<td>sí</td>\n</tr>\n<tr>\n<td>inferior</td>\n<td>getValor() == MIN</td>\n<td>sí</td>\n<td>no</td>\n</tr>\n</tbody>\n</table>\n\n&lt;img&gt;Blue V icon&lt;/img&gt; &lt;img&gt;Green circle with white checkmark icon&lt;/img&gt;\n\n&lt;page_number&gt;26&lt;/page_number&gt;\n\n---\n\n\n## Page 27\n\n# Métodos protegidos\n## Esperas con protección y notificaciones\n\n// continua de la transparencia anterior\n\n```java\npublic synchronized void dec() throws InterruptedException {\n    esperarSalirEstadoInferior();\n    setValor(valor - 1);\n}\n```\n\n```java\nprotected void esperarSalirEstadoInferior() throws InterruptedException{\n    while (valor == MIN)\n        wait();\n}\n```\n\n```java\nprotected void setValor(long nuevoValor) { // PRE: bloqueo adquirido\n    valor = nuevoValor;\n    notifyAll(); // Despierta a todos los hilos que dependen del valor\n}\n```\n\n&lt;img&gt;V&lt;/img&gt; &lt;img&gt;Checkmark&lt;/img&gt;\n&lt;page_number&gt;27&lt;/page_number&gt;\n\n---\n\n\n## Page 28\n\n# Métodos protegidos\n## Más tipos de esperas y notificaciones\n\n*   **Esperas temporizadas**\n    *   En lugar de esperar indefinidamente a que una condición pase a ser verdadera dentro de un método protegido se imponen una cota superior de tiempo\n        *   - wait(long timeout)\n*   **Notificaciones simples**\n    *   Mejora la eficiencia de computación en notificaciones innecesarias\n    *   Se despierta sólo a un hilo del conjunto de espera\n        *   - notify()\n\n&lt;page_number&gt;28&lt;/page_number&gt;\n\n---\n\n\n## Page 29\n\n# Métodos protegidos\n## Más tipos de esperas y notificaciones\n\n*   **Esperas ocupadas**\n    *   Se utiliza en estilos optimistas de reintentos con espera ocupada basada en un bucle activo\n*   No utilizar con acciones protegidas\n\n```java\nprotected esperaOcupadaHastaCond() {\n    while (!cond)\n        Thread.yield();\n}\n```\n&lt;img&gt;V logo&lt;/img&gt;\n\n&lt;page_number&gt;29&lt;/page_number&gt;\n\n---\n\n\n## Page 30\n\n# Métodos protegidos\n## Uso de bibliotecas\n\n*   **Adquisición de bloqueos sobre un objeto**\n    *   Interface `java.util.concurrent.locks.Lock`\n    *   Clase `java.util.concurrent.locks.ReentrantLock`\n        *   Constructor que recibe un booleano indicando si aplicar o no la política de equidad.\n        *   Si es true:\n            *   El objeto que lleva más tiempo esperando entra.\n            *   Evita la inanición (starvation) de las tareas: la tarea es incapaz de ganar el acceso al recurso y nunca pasa a ejecución “muriendo por inanición”\n        *   Permite volverse atrás en la adquisición de bloqueos\n    *   lock() para la adquisición, si está ocupado queda en espera.\n    *   unlock() para la liberación\n    *   tryLock() obtiene el bloqueo retornando true, sólo si esta libre en el momento de la petición, en caso contrario retorna inmediatamente un valor false.\n    *   lockInterruptibly() obtiene el bloqueo salvo que el hilo sea interrumpido.\n\n&lt;page_number&gt;30&lt;/page_number&gt;\n\n---\n\n\n## Page 31\n\n# Métodos protegidos\n## Uso de bibliotecas\n\n*   Condiciones para proseguir la tarea\n    *   newCondition de la interfaz Lock\n        -   Devuelve un objeto que implementa la interfaz java.util.concurrent.locks.Condition\n*   Métodos sobre el objeto Condition obtenido:\n    *   await\n        *   libera el bloqueo coloca a la tarea en espera\n        *   similar al uso de condiciones y método wait\n    *   signal\n        *   hace que la tarea bloqueada con más tiempo de espera pase a ejecutable\n        *   similar al uso de condiciones y método notify\n    *   signalAll\n        *   hace que todas las tarea en espera pasen a ejecutable\n        *   similar al uso de condiciones y método notifyAll\n\n&lt;page_number&gt;31&lt;/page_number&gt;\n\n---\n\n\n## Page 32\n\n# Métodos protegidos\n## Uso de bibliotecas\n\n*   Uso de bloqueos (Lock) y condiciones (Condition)\n\n```java\nLock lock = new ReentrantLock();\nCondition condición1 = lock.newCondition();\n// podemos definir distintas condiciones\nCondition condición2 = lock.newCondition();\n\npublic void bloqueRestringidoConLockAndCondition() {\n    lock.lock();\n    try {\n        while (!cond) { // restricción\n            try {\n                condición1.await(); // espera\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }\n        cond = false; // cambiar estado\n        condición2.signalAll(); // liberar\n    } finally {\n        lock.unlock();\n    }\n}\n```\n\n&lt;img&gt;V&lt;/img&gt;\n&lt;page_number&gt;32&lt;/page_number&gt;\n\n---\n\n\n## Page 33\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   **Intención**\n    *   Coordinar la producción y consumo asíncrono de información\n*   **Contexto**\n\n<mermaid>\ngraph LR\n    subgraph PRODUCTOR\n        A[Producir]\n        B[Esperar]\n        C[Comunicar]\n    end\n\n    subgraph CONSUMIDOR\n        D[Consumir]\n        E[Esperar]\n        F[Comunicar]\n    end\n\n    A --> B\n    B --> C\n    C --> A\n\n    E --> F\n    F --> E\n\n    style A fill:#f9f,stroke:#333,stroke-width:2px\n    style D fill:#f9f,stroke:#333,stroke-width:2px\n</mermaid>\n\n**Paso de X**\n\n<table>\n  <tr>\n    <td>\n      1. Notificar que <span style=\"color:red;\">productor</span> no está preparado<br>\n      2. Efectuar cálculos que produzcan un valor de <span style=\"color:red;\">x</span><br>\n      3. Notificar que <span style=\"color:red;\">productor</span> está preparado<br>\n      4. Esperar a que el <span style=\"color:red;\">consumidor</span> esté preparado<br>\n      5. Pasar <span style=\"color:red;\">x</span> al <span style=\"color:red;\">consumidor</span>\n    </td>\n    <td>\n      1. Notificar que <span style=\"color:red;\">consumidor</span> está preparado<br>\n      2. Esperar a que el <span style=\"color:red;\">productor</span> esté preparado<br>\n      3. Obtener <span style=\"color:red;\">x</span> del <span style=\"color:red;\">productor</span><br>\n      4. Notificar que <span style=\"color:red;\">consumidor</span> no está preparado<br>\n      5. Efectuar un cálculo que utiliza el valor de <span style=\"color:red;\">x</span>\n    </td>\n  </tr>\n</table>\n\n---\n\n\n## Page 34\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   **Fuerzas** – cuando aplicar el patrón-\n    *   Los objetos son producidos o recibidos de **forma asíncrona** para su utilización o consumo\n    *   Cuando un objeto se recibe o se produce pero podría no haber objetos disponibles para ser usados o consumidos\n*   **Solución**\n\n```mermaid\nclassDiagram\n    class Dato {\n        dato : Object\n        +setDato(o:Object){conurrencia=espera | ¿hay espacio?}\n        +getDato():Object {conurrencia=espera | ¿hay datos?}\n    }\n    class Producer {\n        0..* produce datos -> 1 Dato\n    }\n    class Consumer {\n        1 consume datos -> 0..* Dato\n    }\n    Producer --|> java.lang.Runnable : run()\n    Consumer --|> java.lang.Runnable : run()\n```\n\n&lt;page_number&gt;34&lt;/page_number&gt;\n\n---\n\n\n## Page 35\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   **Ejemplo de código**\n\n```java\npublic class Dato {\n    private int dato = -1;\n    private boolean sepuedeescibir = true;\n    public synchronized void setDato(int val) {\n        while (!sepuedeescibir) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n                System.out.print(e.toString());\n            }\n        }\n        dato = val;\n        sepuedeescibir = false;\n        notify();\n    }\n    public synchronized int getDato() {\n        while (sepuedeescibir) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n                System.out.print(e.toString());\n            }\n        }\n        sepuedeescibir = true;\n        notify();\n        return dato;\n    }\n}\n```\n\n```java\npublic class Dato {\n    private int dato = -1;\n\n    public void setDato(int val){\n        dato = val;\n    }\n\n    public int getDato(){\n        return dato;\n    }\n}\n```\n\n&lt;img&gt;Red arrow pointing to the right&lt;/img&gt;\n&lt;img&gt;Blue circle with white checkmark&lt;/img&gt; &lt;img&gt;Red circle with white cross&lt;/img&gt;\n\n&lt;page_number&gt;35&lt;/page_number&gt;\n\n---\n\n\n## Page 36\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   **Ejemplo de código**\n\n```java\npublic class Consumidor extends Thread {\n    private Dato recurso;\n    public Consumidor(Dato r) {\n        super(\"Consumidor\");\n        recurso = r;\n    }\n    public void run() {\n        int val, sum = 0;\n        do {\n            try {\n                Thread.sleep((int)(Math.random() * 3000));\n            } catch (InterruptedException e) {\n                System.err.println(e.toString());\n            }\n            val = recurso.getDato();\n            System.out.println(\" El consumidor recupero \" + val + \" del recurso compartido\\n\");\n            sum++;\n        } while (val != 5);\n        System.out.println(\"Fin del consumidor: El número total de valores consumidos es:\" + sum);\n    }\n}\n```\n\n&lt;img&gt;Blue V icon&lt;/img&gt;&lt;img&gt;Green checkmark icon&lt;/img&gt;\n\n---\n\n\n## Page 37\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   **Ejemplo de código**\n```java\npublic class Productor extends Thread {\n    private Dato recurso;\n\n    public Productor(Dato r) {\n        super(\"Productor\");\n        recurso = r;\n    }\n\n    public void run() {\n        for (int contador = 1; contador <= 5; contador++) {\n            try {\n                Thread.sleep((int)(Math.random() * 3000));\n            } catch (InterruptedException e) {\n                System.err.println(e.toString());\n            }\n            recurso.setDato(contador);\n            System.out.println(\" El productor puso \" + contador + \" en el recurso compartido\\n\");\n        }\n    }\n\n    System.err.println(\"\\n*** Fin del productor:\");\n}\n```\n&lt;img&gt;Blue V logo&lt;/img&gt;&lt;img&gt;Green circle with white checkmark logo&lt;/img&gt;\n\n---\n\n\n## Page 38\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   Ejemplo de código\n\n```java\npublic class TestProductorConsumidor {\n    public static void main(String args[]) {\n        Dato r = new Dato();\n        Productor p = new Productor(r);\n        Consumidor c = new Consumidor(r);\n        p.start();\n        c.start();\n    }\n}\n```\n&lt;img&gt;Blue V icon&lt;/img&gt; &lt;img&gt;Green circle with checkmark icon&lt;/img&gt;\n\nSalida de ejecución\n\nEl productor puso 1 en el recurso compartido\nEl consumidor recupero 1 del recurso compartido\nEl productor puso 2 en el recurso compartido\nEl consumidor recupero 2 del recurso compartido\nEl productor puso 3 en el recurso compartido\nEl consumidor recupero 3 del recurso compartido\nEl productor puso 4 en el recurso compartido\nEl consumidor recupero 4 del recurso compartido\nEl productor puso 5 en el recurso compartido\n*** Fin del productor:\nEl consumidor recupero 5 del recurso compartido\nFin del consumidor: El número total de valores consumidos es:5\n\n&lt;img&gt;Timeline diagram showing two threads (Consumidor and Productor) running concurrently. The timeline is labeled \"Threads\" with \"0:00\" and \"[m:s]\" at the top right. The legend at the bottom indicates colors for Running, Sleeping, Wait, and Monitor.&lt;/img&gt;\n\n&lt;page_number&gt;38&lt;/page_number&gt;\n\n---\n\n\n## Page 39\n\n# Patrones de diseño concurrente\n## Productor- Consumidor\n\n*   Uso `java.util.concurrent.BlockingQueue`\n\n```java\nclass Producer implements Runnable {\n    private final BlockingQueue queue;\n    Producer(BlockingQueue q) {\n        queue = q;\n    }\n    public void run() {\n        try {\n            while (true) { queue.put(produce()); }\n        } catch (InterruptedException ex) { ... handle ... }\n    }\n}\nObject produce() { ... }\n```\n\n```java\npublic class TestBlockingQueue {\n    public static void main(String[] args) {\n        BlockingQueue q = new SomeQueueImplementation();\n        Producer p = new Producer(q);\n        Consumer c1 = new Consumer(q);\n        Consumer c2 = new Consumer(q);\n        new Thread(p).start();\n        new Thread(c1).start();\n        new Thread(c2).start();\n    }\n}\n```\n\n```java\nclass Consumer implements Runnable {\n    private final BlockingQueue queue;\n    Consumer(BlockingQueue q) {\n        queue = q;\n    }\n    public void run() {\n        try {\n            while (true){ consume(queue.take()); }\n        } catch (InterruptedException ex) {\n            ... handle ...\n        }\n    }\n    void consume(Object x) { ... }\n}\n\n---\n\n\n## Page 40\n\n# Patrones de diseño concurrente\n## Bloqueo Lectura/Escritura\n\n*   **Intención**\n    *   Permitir accesos de lectura concurrente a un objeto pero se requiere accesos exclusivos para operaciones de escritura\n*   **Fuerzas**\n    *   Hay necesidad de leer y escribir información de estado de un objeto\n    *   Pueden realizarse operaciones de lectura concurrentemente. La lectura es segura sólo si no hay operaciones de escritura ejecutándose concurrentemente\n    *   La lógica para coordinar las operaciones de lectura y escritura se puede reutilizar\n\n&lt;page_number&gt;40&lt;/page_number&gt;\n\n---\n\n\n## Page 41\n\n# Patrones de diseño concurrente\n## Bloqueo Lectura/Escritura\n\n*   **Solución**\n    *   La abstracción Dato utiliza los bloqueos coordinados de lectura y escritura\n\n```java\nimport java.util.concurrent.locks.ReadWriteLock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\npublic class DatoRW {\n    private int dato;\n    private final ReadWriteLock lock = new ReentrantReadWriteLock();\n    public DatoRW(int dato) {\n        super();\n        this.dato = dato;\n    }\n    public int getDato() {\n        lock.readLock().lock();\n        int datoaux = dato;\n        lock.readLock().unlock();\n        return datoaux;\n    }\n    public void setDato(int dato){\n        lock.writeLock().lock();\n        this.dato = dato;\n        lock.writeLock().unlock();\n    }\n}\n```\n\n```mermaid\nclassDiagram\n  class Dato {\n    dato : Object\n    +setDato(o:Object){conurrencia=espera | ¿bloqueos de R o W?}\n    +getDato():Object {conurrencia=espera | ¿bloqueos de W?}\n  }\n  class ReadWriteLock {\n    readLock()\n    writeLock()\n  }\n  Dato \"1\" -- \"*\" ReadWriteLock : Usa\n\n---\n\n\n## Page 42\n\n# Patrones de diseño concurrente\n## Bloqueo Lectura/Escritura\n\n*   Solución\n\n```java\npublic abstract class ReadWrite {\n    protected int activeReaders = 0; // threads executing read\n    protected int activeWriters = 0; // always zero or one\n\n    protected int waitingReaders = 0; // threads not yet in read\n    protected int waitingWriters = 0; // same for write\n\n    protected abstract void doRead(); // implement in subclasses\n\n    protected abstract void doWrite();\n\n    public void read() throws InterruptedException {\n        beforeRead();\n        try {\n            doRead();\n        } finally {\n            afterRead();\n        }\n    }\n\n    public void write() throws InterruptedException {\n        beforeWrite();\n        try {\n            doWrite();\n        } finally {\n            afterWrite();\n        }\n    }\n\n    protected boolean allowReader() {\n        return waitingWriters == 0 && activeWriters == 0;\n    }\n}\n```\n&lt;page_number&gt;42&lt;/page_number&gt;\n\n---\n\n\n## Page 43\n\n# Patrones de diseño concurrente\n## Bloqueo Lectura/Escritura\n\n*   Solución\n\n```java\nprotected boolean allowWriter() {\n    return activeReaders == 0 && activeWriters == 0;\n}\n\nprotected synchronized void beforeRead() throws InterruptedException {\n    ++waitingReaders;\n    while (!allowReader()) {\n        try {\n            wait();\n        } catch (InterruptedException ie) {\n            --waitingReaders; // roll back state\n            throw ie;\n        }\n    }\n    --waitingReaders;\n    ++activeReaders;\n}\n\nprotected synchronized void afterRead() {\n    --activeReaders;\n    notifyAll();\n}\n\nprotected synchronized void beforeWrite() throws InterruptedException {\n    ++waitingWriters;\n    while (!allowWriter()) {\n        try {\n            wait();\n        } catch (InterruptedException ie) {\n            --waitingWriters;\n            throw ie;\n        }\n    }\n    --waitingWriters;\n    ++activeWriters;\n}\n\nprotected synchronized void afterWrite() {\n    --activeWriters;\n    notifyAll();\n}\n\n---\n\n\n## Page 44\n\n# Bibliografía\n\n*   **Libros y manuales**\n    *   Doug Lea. Programación concurrente en Java: Principios y patrones de diseño. 2ª ed. PEARSON EDUCACION, 2000. Tema 3.\n        http://gee.cs.oswego.edu/dl/cpj/.\n    *   Oracle. «Lesson: Concurrency (The Java™ Tutorials > Essential Classes)». Accedido enero 23, 2013.\n        http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html.\n    *   Grand, Mark. Patterns in Java. Volumen 1. A Catalog of Reusable Design Patterns Illustrated with UML. Wiley computer publishing. New York John Wiley and Sons Inc, 1998. Tema 9\n\n*   **Enlaces de interés**\n    *   «Java Concurrent Animated | Free Home & Education software downloads at SourceForge.net». Accedido enero 23, 2013.\n        http://sourceforge.net/projects/javaconcurrenta/.\n\n&lt;page_number&gt;44&lt;/page_number&gt;",
      "metadata": {}
    }
  }
}