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(); } } } }
每次消费与生产都是同一个,说明实验正确。