1、什么是“生产者和消费者模式”?
生产线程负责生产,消费线程负责消费
生产线程和消费线程要达到均衡
这是一种特殊的业务需求,在这种特殊的情况下需要使用wait方法和notify方法
2、wait和notify方法不是线程对象的方法,是普通java对象都有的方法
3、wait和notify方法建立在线程同步的基础之上。因为多线程要同时操作一个仓库。有线程安全问题
4、wait方法作用:o.wait()让正在o对象上活动的线程t进入等待状态,并且释放掉t线程之前占有的o对象的锁
5、notify方法作用:o.notify()让正在o对象上等待的线程唤醒,只是通知,不会释放o对象上之前占有的锁
6、模拟需求:
仓库我们采用List集合
List集合中假设只能存储一个元素
1个元素就表示仓库满l
如果List集合中元素个数是0,就表示仓库空了
保证List集合中永远都是最多存储一个元素了
必须做到,生产一个,消费一个
示例代码01:
public class ThreadTest16 { public static void main(String[] args) { //创建一个仓库对象,共享的 List list = new ArrayList(); //创建对象 //创建生产者对象 Thread t1 = new Producter(list); //创建消费者对象 Thread t2 = new Consumer(list); t1.setName("生产者线程"); t2.setName("消费者线程"); //启动线程 t1.start(); t2.start(); } } //生产者线程 class Producter extends Thread{ private List list; public Producter(List list){ this.list = list; } public void run(){ while(true) { synchronized (list) { if (list.size() > 0) { try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Object obj = new Object(); list.add(obj); System.out.println(Thread.currentThread().getName() + "--->" + obj); //线程唤醒 list.notifyAll(); } } } } //消费者线程 class Consumer extends Thread{ private List list; public Consumer(List list){ this.list = list; } public void run(){ while(true){ synchronized (list) { if (list.size() == 0) { try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Object obj = list.remove(0); System.out.println(Thread.currentThread().getName() + "--->" + obj); list.notifyAll(); } } } }
运行结果:
使用生产者和消费者模式实现,交替输出:
假设只有两个线程,输出以下结果:
t1—>1
t2—>2
t3—>3
t4—>4
t5—>5
t6—>6
t7—>7
要求:必须交替执行,并且t1线程负责输出奇数,t2线程输出偶数
两个线程共享一个数字,每个线程执行时都要对这个数字进行:++
示例代码02:
public class ThreadTest { public static void main(String[] args) { //创建数字类对象 Num num = new Num(); //创建生产者对象 Thread t1 = new Producter(num); //创建消费者对象 Thread t2 = new Consumer(num); //修改线程名字 t1.setName("t1"); t2.setName("t2"); //启动线程 t1.start(); t2.start(); } } //共享数据 class Num{ int i = 1; } //生产者线程 class Producter extends Thread{ private Num num; public Producter(Num num){ this.num = num; } public void run(){ while(true){ synchronized (num) { if ((num.i % 2) == 0) { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "--->" + num.i++); try { //延迟1秒输出 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } num.notifyAll(); } } } } //消费者线程 class Consumer extends Thread{ private Num num; public Consumer(Num num){ this.num = num; } public void run(){ while(true){ synchronized (num) { if ((num.i % 2) == 1) { try { num.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "--->" + num.i++); try { //延迟一秒输出 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } num.notifyAll(); } } } }
运行结果: