线程间通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同
重点:有效的利用资源
分析:需要那些类
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();
}