等待和唤醒实现Java线程间通信

Java的线程间通信,其实就是利用等待和唤醒机制达到多个线程之间协调工作的目的。

1. 等待和唤醒

Object类中有两个方法,wait()和notify()。这两个方法时在多线程中被锁对象调用的。因为所对象可以是任意对象,为了让任意对象都能调用这两个方法,所以把这两个方法设计到了Object方法中

void wait()  
  让当先正在执行的线程进入无限等待状态
void notify()
  唤醒正在等待的线程

很经典的一个例子,就是生产者和消费者的案例。假设包子铺生产一个包子,吃货就要吃一个包子。用两个线程分别表示包子铺和吃货 ,包子铺线程生产一个包子,吃货线程就吃一个包子。

2. 案例分析

包子铺 和 吃货的共性数据就是包子。可以把包子当做锁对象。当两个线程共用一把锁的时候,就可以让两个线程达到互斥的效果(ps: 所谓互斥就是我执行你不执行;你执行我不执行)。

3. 代码实现

先写一个包子类

public class BaoZi {
    private String pi; //包子皮
    private String xian; //包子馅
    private boolean flag;//包子状态 true表示有包子,false表示包子被吃了

    public String getPi() {
        return pi;
    }

    public void setPi(String pi) {
        this.pi = pi;
    }

    public String getXian() {
        return xian;
    }

    public void setXian(String xian) {
        this.xian = xian;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}
Copy

再写一个包子铺线程

public class BaoZiPu implements Runnable{
    private BaoZi bz;
    //通过构造方法给BaoZi对象赋值
    public BaoZiPu(BaoZi bz){
        this.bz=bz;
    }

    public void run(){
        while(true){
            synchronized (bz){
                //如果有包子,包子铺等待
                if(bz.isFlag()){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果等待结束了,就生产包子
                System.out.println("包子铺生产了一个"+bz.getPi()+"..."+bz.getXian()+"的包子");
                //生产好了包子把包子状态太为true
                bz.setFlag(true);
                bz.notify();//把等待的吃货线程唤醒
            }
        }
    }
}

再写一个吃货线程

public class ChiHuo implements Runnable{
    private BaoZi bz;
    //通过构造方法给BaoZi对象赋值
    public ChiHuo(BaoZi bz){
        this.bz=bz;
    }

    public void run(){
        while(true){
            synchronized (bz){
                //如果没有包子,吃货等待
                if(!bz.isFlag()){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果吃货等待结束了,就吃包子
                System.out.println("吃货吃了一个"+bz.getPi()+"..."+bz.getXian()+"的包子");
                //吃货吃完包子把包子状态太为false
                bz.setFlag(false);
                bz.notify();//把等待的包子铺线程唤醒
            }
        }
    }
}

再写测试类

public class Test{
  public static void main(String[] args){
    Baozi bz=new Baozi();
    bz.setPi("冰皮");
    bz.setXian("牛肉馅");

    //创建包子铺线程,开启
    new Thread(new BaoZiPu(bz)).start();
    //创建吃货线程,开启
    new Thread(new ChiHuo(bz)).start();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值