java线程通讯之wait与notify
概述
wait与notify方法是jdk定义在Object类中的方法,因此所有类实例都可以成为用来实现线程之间通讯的监视器
Object类中方法定义
/**
* 会使调用线程状态变更为WATING状态 并且 会释放锁
*/
public final void wait() throws InterruptedException;
/**
* 会随机唤醒等在当前监视器的1个线程
*/
public final native void notify();
/**
* 唤醒所有等待在当前监视器的线程
*/
public final native void notifyAll();
使用时注意事项
-
必须在syncronized代码块内中调用
-
注意死锁问题
作用
-
让线程处于等待状态
-
生产者消费者 实现
线程之间通讯的例子
以下示例实现一个 一问一答的线程通讯
package com.nanxhs.concurrent.thread.message;
/**
* @author: haibin.tang
* @date: 2021/1/27
*/
public class Question {
private int a;
private int b;
public Question(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
}
package com.nanxhs.concurrent.thread.message;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* 为了测试 Object.wait 与 Object.notify的使用
* @author: haibin.tang
* @date: 2021/1/27
*/
public class ChatService {
/**
* 监视器锁
*/
private final Object MONITOR = new Object();
/**
* 问题
*/
private Question question;
/**
* 问题线程
*/
public void a() {
new Thread(() -> {
synchronized (MONITOR) {
while (true) {
try {
question = new Question((int)(Math.random() * 1000), (int)(Math.random() * 100));
System.out.println("问题: " + question.getA() + " + " + question.getB() + " = ?");
//随机唤醒其它等待在 MONITOR 监视器的线程
MONITOR.notify();
//让当前线程等待并且释放锁
MONITOR.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
/**
* 计算答案的线程
*/
public void b() {
new Thread(() -> {
synchronized (MONITOR) {
while (true) {
if (Objects.isNull(question)) {
try {
//随机唤醒其它等待在 MONITOR 监视器的线程
MONITOR.notify();
//让当前线程等待并且释放锁
MONITOR.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//当前线程阻塞1秒
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
System.out.println("答案: " + (question.getA() + question.getB()));
//当前线程阻塞1秒
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
question = null;
//随机唤醒其它等待在 MONITOR 监视器的线程
MONITOR.notify();
try {
//让当前线程等待并且释放锁
MONITOR.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
public static void main(String[] args) {
ChatService chatService = new ChatService();
chatService.a();
chatService.b();
}
}
运行结果
问题: 586 + 89 = ?
答案: 675
问题: 733 + 53 = ?
答案: 786
问题: 737 + 21 = ?
答案: 758
问题: 347 + 10 = ?
答案: 357
问题: 991 + 17 = ?
答案: 1008
.....
.....

浙公网安备 33010602011771号