线程间通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同
重点:有效的利用资源
分析:需要那些类
1 资源类:包子类
- 设置包子的属性
- 包子的状态:有true 没有false
2 生产者(包子铺)类:是一个线程类,可以继承Thread
- 设置线程任务(run):生产包子
- 对包子的状态进行判断
true:有包子
- 包子铺调用wait方法进入等待状态
false:没有包子
- 包子铺生产包子
- 增加一些多样性:交替生产两种包子
- 有两种状态(i%2 == 0 )
- 包子铺生产好了包子
- 修改包子的状态为true有
- 唤醒吃货线程,让吃货线程吃包子
3 消费者(吃货)类:是一个线程类,可以继承Thread
- 设置线程任务(run):吃包子
- 对包子的状态进行判断
false:没有包子
- 吃货线程调用wait方法进入等待状态
true:有包子
- 吃货吃包子
- 吃货吃完包子
- 修改包子的状态为false没有
- 吃货唤醒包子铺线程,生产包子
4 测试类:
- 包含main方法,程序执行的入口,启动程序
- 创建包子对象:
- 创建包子铺线程,开启,生产包子
- 创建吃货线程,开启,吃包子;
注意:
- 包子铺线程和包子线程关系-->通信(互斥)、
- 必须同时同步技术保证两个线程只能有一个在执行
- 锁对象必须保证唯一,可以使用包子对象作为锁对象
- 包子铺类和吃货的类就需要把包子对象作为参数传递进来
- 需要在成员位置创建一个包子变量
- 使用带参数的构造方法,为这个包子变量赋值
public class CaiNiao{ public static void main(String[] args){ //创建锁对象,保证唯一 Object obj = new Object(); //创建一个顾客线程(消费者) new Thread(){ @Override public void run(){ //一直等着买包子 while(true){ //保证等待和唤醒的线程只能有一个执行,需要使用同步技术 syncharonized (obj){ System.out.println("告知老板要的包子的种类和数量"); //调用wait方法,放弃cpu的执行,进入到WAITNG状态(无限等待) try{ obj.wait(); }catch (InterruptedException e){ e.printStackTrace(); } //唤醒之后执行的代码 System.out.println("包子已经做好了,开吃!"); System.out.println("--------------"); } } } }.start(); //创建一个老板线程(生产者) new Thread(){ @Override public void run(){ //一直做包子 while(true){ //花5秒做包子 try{ Thread.sleep(5000);//花5秒做包子 }catch(InterruptedException e); e.printStackTrace(); } //保证等待和唤醒只能有一个在执行,需要使用同步技术 syncharonized (obj){ System.out.println("花了5秒做包子,做好包子之后,调用notify方法,唤醒顾客吃包子"); //做好包子之后,调用notify方法,唤醒顾客吃包子 obj.notify(); } } }.start(); }