Comunicación entre hilos en Java con wait y notify

Índice- Descripción general

  • Definición de métodos en la clase Object
  • Notas de uso
  • Funcionalidad
  • Ejemplo de comunicación entre hilos
  • Resultado de ejecución

Descripción general

Los métodos wait y notify están definidos en la clase Object del JDK, por lo que cualquier instancia de clase puede actuar como monitor para la comunicación entre hilos

Definición de métodos en la clase Object

/**
* Pone al hilo en estado de espera y libera el bloqueo
*/
public final void wait() throws InterruptedException;
/**
* Despierta aleatoriamente a un hilo en espera
*/
public final native void notify();
/**
* Despierta a todos los hilos en espera
*/
public final native void notifyAll();


Notas de uso

  1. Deben usarse dentro de bloques sincronizados
  2. Prestar atención a posibles deadlocks

Funcionalidad

  1. Poner hilos en estado de espera
  2. Implementación de patrón productor-consumidor

Ejemplo de comunicación entre hilos

El siguiente ejemplo implementa una comunicación pregunta-respuesta entre hilos

package com.nanxhs.concurrent.thread.message;

/**
 * @author: haibin.tang
 * @date: 2021/1/27
 */
public class Query {
    private int num1;
    private int num2;

    public Query(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

    public int getNum1() {
        return num1;
    }

    public int getNum2() {
        return num2;
    }
}


package com.nanxhs.concurrent.thread.message;

import java.util.Objects;

/**
 *  Ejemplo de uso de Object.wait y Object.notify
 * @author: haibin.tang
 * @date: 2021/1/27
 */
public class ThreadCommunicationExample {
    /**
     * Objeto bloqueo
     */
    private final Object lock = new Object();
    /**
     * Consulta actual
     */
    private Query query;

    /**
     * Hilo generador de preguntas
     */
    public void startQuestionThread() {
        new Thread(() -> {
            synchronized (lock) {
                while (true) {
                    try {
                        query = new Query((int)(Math.random() * 1000), (int)(Math.random() * 100));
                        System.out.println("Pregunta: " + query.getNum1() + " + " + query.getNum2() + " = ?");
                        // Despierta a otro hilo
                        lock.notify();
                        // Espera y libera bloqueo
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    /**
     * Hilo resolviendo preguntas
     */
    public void startAnswerThread() {
         new Thread(() -> {
            synchronized (lock) {
                while (true) {
                    if (Objects.isNull(query)) {
                        try {
                            // Despierta a otro hilo
                            lock.notify();
                            // Espera y libera bloqueo
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        // Pausa 1 segundo
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("Respuesta: " + (query.getNum1() + query.getNum2()));
                        // Pausa 1 segundo
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        query = null;
                        // Despierta a otro hilo
                        lock.notify();
                        try {
                            // Espera y libera bloqueo
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

    public static void main(String[] args) {
        ThreadCommunicationExample example = new ThreadCommunicationExample();
        example.startQuestionThread();
        example.startAnswerThread();
    }
}


Resultado de ejecución

Pregunta: 586 + 89 = ?
Respuesta: 675
Pregunta: 733 + 53 = ?
Respuesta: 786
Pregunta: 737 + 21 = ?
Respuesta: 758
Pregunta: 347 + 10 = ?
Respuesta: 357
Pregunta: 991 + 17 = ?
Respuesta: 1008
.....
.....

Etiquetas: java hilos sincronización wait notify

Publicado el 8-27 12:14