Í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
- Deben usarse dentro de bloques sincronizados
- Prestar atención a posibles deadlocks
Funcionalidad
- Poner hilos en estado de espera
- 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
.....
.....