1、wait 和 notify 不是线程对象的方法,而是Java中任何一个对象都有的方法。
2、wait 和 notify 方法的作用:
wait:让正在活动在该对象上的线程进入等待状态,无限期等待,直到被唤醒为止
notify:让正在该对象上等待的线程被唤醒
notifyAll():唤醒所有等待的线程
3、使用 wait 和 notify 方法,要建立在线程同步的基础上,wait 会让活动在当前对象的线程进入等待状态,并且释放占有对象的 "锁" 。
4、通过一个实例来熟悉wait 和 notify 方法
要求:使用 wait 和 notify 模拟生产者模式 和消费者模式。使用List集合模拟仓库,仓库中只能存在一个元素,有一个元素就必须进行消费,仓库为空必须进行生产,要求达到均衡,
分析:
仓库是共享的对象,生产与消费代表俩个线程,俩个线程共享仓库对象
public class Test03 {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
Thread produce = new Thread(new Produce(list));
Thread spend = new Thread(new Spend(list));
produce.setName("生产者线程");
spend.setName("消费者线程");
produce.start();
spend.start();
}
}
//生产线程
class Produce implements Runnable {
//仓库,共享的对象
private List<Object> list;
public Produce(List<Object> list) {
this.list = list;
}
@Override
public void run() {
while (true) {
synchronized (list) {
if (!list.isEmpty()) {
try {
//表示集合不为空,该去消费.
//此时生产者线程遇到wait() 会释放list对象的"锁",并等待消费者线程执行
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//集合为空,应该生产
Object data = new Object();
list.add(data);
System.out.println(Thread.currentThread().getName() + "生产--》" + data);
//生产完唤醒线程,并不会释放对象 "锁",而是接着执行while循环。如果集合不为空,才会执行wait(),释放锁,让消费线程执行
list.notify();
}
}
}
}
//消费线程
class Spend implements Runnable {
private List<Object> list;
public Spend(List<Object> list) {
this.list = list;
}
@Override
public void run() {
while (true) {
synchronized (list) {
if (list.isEmpty()) {
//集合为空,该去生产
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//集合不为空,进行消费
Object data = list.remove(0);
System.out.println(Thread.currentThread().getName() + "消费--》" + data);
list.notify();
}
}
}
}
每次消费与生产都是同一个,说明实验正确。