一、等待/通知机制 notify/wait
等待/通知的相关方法是任意java对象都具备的。原因是这些方法被定义在超类
Object上面。
1.notify() 通知一个在对象上等待的线程使其从main()方法中返回,返回的前
提是获取到了对象锁。
2.notifyAll():通知所有等待的线程在该对象的线程
3.wait():使该线程进入WAITING状态(等待),只有等待其他线程通知或者是中断,
调用wait方法后会释放该线程的锁。
注意:notify和wait方法需要结合synchronized使用
二、wait和notify的简单使用
public class ThreadDemo01 extends Thread {
@Override
public void run() {
try {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + ">>当前线程阻塞,同时释放锁!<<");
this.wait();
}
System.out.println(">>run()<<");
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
Thread03 thread = new Thread03();
thread.start();
try {
Thread.sleep(3000);
} catch (Exception e) {
}
synchronized (thread) {
// 唤醒正在阻塞的线程
thread.notify();
}
}
}
三、使用notify和wait实现生产者和消费者
public class ThreadDemo02 {
class Res {
/**
* 姓名
*/
private String userName;
/**
* 性别
*/
private char sex;
/**
* 标记 限制消费者和生产者的执行顺序
*/
private boolean flag = false;
}
class InputThread extends Thread {
private Res res;
public InputThread(Res res) {
this.res = res;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (res) {
//flag = false 写入输入 flag = true 则不能写入数据 只能读取数据
try {
// 如果flag = true 则不能写入数据 只能读取数据 同时释放锁!
if (res.flag) {
res.wait();
}
} catch (Exception e) {
}
if (count == 0) {
this.res.userName = "小红";
this.res.sex = '女';
} else {
this.res.userName = "小明";
this.res.sex = '男';
}
res.flag = true;
res.notify();
}
// 为了两个信息进行切换
count = (count + 1) % 2;
}
}
}
class OutThread extends Thread {
private Res res;
public OutThread(Res res) {
this.res = res;
}
@Override
public void run() {
while (true) {
synchronized (res) {
try {
if (!res.flag) {
res.wait();
}
} catch (Exception e) {
}
System.out.println(res.userName + "," + res.sex);
res.flag = false;
res.notify();
}
}
}
}
public static void main(String[] args) {
new ThreadDemo02().print();
}
public void print() {
Res res = new Res();
InputThread inputThread = new InputThread(res);
OutThread outThread = new OutThread(res);
inputThread.start();
outThread.start();
}
}
主要思路:先让生产者生产信息,消费者后消费信息,生产者每次生产完成
时候就将标记设成消费者执行标志执行完毕后,反之设置生产者生产标志
,两者由flag来进行操控先后顺序结果就是两个信息轮询打印。