简单描述线程间的通信机制(等待和唤醒机制),完成生产者和消费者案例;

等待唤醒机制

等待唤醒机制,是指一个线程A调用了对象Object的wait()方法进入等待状态,而另一个线程B调用了对象Object的notify()或者notifyAll()方法,线程A收到了通知后,从对象Object的wait()方法返回,进而执行后续操作。

上述两个线程通过Object对象来完成交互,而对象上的wait()和notify()/notifyAll()的关系就如同开关信号一样,用来完成等待方和通知方的交互工作。

等待/通知的相关方法是任意Java类对象都具备的,Object类都有实现

生产者和消费者案例:

包子铺(生产者类)

包子铺 线程类;继承Thread类

设置线程任务 生产包子

true 有包子

包子铺调用wait方法进入等待状态

false 没有包子

增加难度:交替生产两种包子

i%2==0 1

包子铺生产包子

修改包子状态 true

唤醒吃货线程去吃包子

注意:包子铺线程和吃货线程关系是—>通信,互斥

必须使用同步技术保证两个线程只能有一个线程在执行

锁对象必须保证唯一,可以使用包子作为对象

包子铺和吃货线程的类需要把包子对象作为参数传递进来。

1.需要在成员位置上创建一个包子变量

2.使用带参构造,为这个包子赋值

吃货类(消费者类)

线程类 ,任务吃包子 继承 Thread
对包子状态进行判断
true 有包子
吃包子
吃完包子
修改包子状态 为false
唤醒包子铺生产包子
false 没有包子
吃货调用wait方法进入等待
资源类

设置包子属性


包子的状态 有true 无false
代码如下
包子类、资源类

public class Baozi {

    String pi;
    String xian;
    
    boolean flag=false;
}

生产者类:

public class Costs extends Thread {

    // 1.需要在成员位置上创建一个包子变量
    private Baozi baozi;

    // 2.使用带参构造,为这个包子赋值
    public Costs(Baozi baozi) {

        this.baozi = baozi;
    }

    @Override
    public void run() {
        // 设置任务
        // 定义一个变量
        int count = 0;
        while (true) {
            // 必须保证两个线程只能有一个在执行
            synchronized (baozi) {
                // 包子状态的判断
                if (baozi.flag) {
                    // 包子铺有包子,包子铺需要调用wait方法进入等待状态
                    try {
                        baozi.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                // 包子铺没有包子,被唤醒之后包子铺生产包子,增加难度:交替生产两种包子
                if (count % 2 == 0) {
                    // 生产三鲜包子,薄皮
                    baozi.pi = "薄皮";
                    baozi.xian = "三鲜";
                } else {
                    baozi.pi = "冰皮";
                    baozi.xian = "猪肉大葱";
                }
                count++;
                System.out.println("包子铺正在生产:"+baozi.pi+baozi.xian+"馅的包子");
                 // 生产包子需要一个过程,等待3秒钟
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //包子铺生产好了包子
                //修改包子状态  true 
                baozi.flag=true;
                //唤醒吃货线程
                baozi.notify();
                System.out.println("包子铺已经生产好了"+baozi.pi+baozi.xian+"馅的包子,吃货可以开始吃了");
            }
        }
    }
}

消费者类:

public class Foodie extends Thread{

    //1.在成员位置上定义一个包子变量
    private Baozi baozi ;
    //2.使用带参构造,为这个包子变量赋值
    public Foodie(Baozi baozi) {
        this.baozi=baozi;
    }
    //3.重写run方法
    @Override
    public void run() {
        
        //设置线程任务,吃包子
        //使用死循环,让吃货吃包子
        while(true) {
            //使用同步锁,保证只有一个线程在执行
            synchronized (baozi) {
                //对包子状态进行判断
                //让吃货进入到等待状态
                if(baozi.flag==false) {
                    try {
                        baozi.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //被唤醒后执行吃包子
                System.out.println("吃货正在吃"+baozi.pi+baozi.xian+"馅的包子");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                //吃货吃完包子,修改包子状态 为false
                baozi.flag=false;
                //吃货线程唤醒包子铺线程生产包子
                baozi.notify();
                System.out.println("吃货已经吃完了"+baozi.pi+baozi.xian+"馅的包子");
                System.out.println("-*-*-*-*-*-");
            }            
        }    
    }
}    

测试类:

public class Test {
    public static void main(String[] args) {    
        Baozi baozi=new Baozi();
        Foodie foodie=new Foodie(baozi);
        Costs costs=new Costs(baozi);    
        foodie.start();
        costs.start();    
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值