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

线程间的等待与唤醒机制,wait和notify是Object的方法,用于线程的等待与唤醒,必须搭配着synchronized来使用,脱离 synchronized 使用 wait 会直接抛出异常

等待方法 

wait

 等待方法做的事

1.调用wait方法的前提是获得这个对象的锁(synchronized对象锁,如果有多个线程取竞争这个锁,只有一个线程获得锁,其他线程会处于等待队列)
2.使当前执行代码的线程进行等待 . ( 把线程放到等待队列中 )
3.调用wait方法会释放锁
4.满足一定条件会重新尝试获得这个锁,被唤醒的之后不是立即恢复执行,而是进入阻塞队列,竞争锁
结束等待的三个方式

1.其他线程调用该对象的 notify 方法.
2.wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本, 来指定等待时间).
3.其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 InterruptedException 异常
 

唤醒方法

notify

notify()随机唤醒一个处在等待状态的线程  
notifyAll()唤醒所有处在等待状态的线程
方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的 其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。
如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程。(并没有 "先来后到") 在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁。

生产者和消费者案例

public class Baozi {
    String name;//包子名称
    boolean flag;//包子的状态(TRUE表示存在   false表示不存在)
}







public class Chihuo extends Thread{
    Baozi baozi;
    public Chihuo(String name,Baozi bz){
        super();
        this.baozi=bz;
    }
    public void run(){
        String threadName=Thread.currentThread().getName();
        int count=0;
        while(true){
            synchronized (baozi){
                count++;
                if(count>10){
                    break;
                }
                if(baozi.flag){
                    System.out.println(threadName+"开始吃"+baozi.name);
                    baozi.flag=false;
                    baozi.notify();
                }else{
                    try{
                        baozi.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }
}









public class Zaocandian extends Thread{
    Baozi baozi;
    public Zaocandian(String name,Baozi bz){
        super();
        this.baozi=bz;
    }

    @Override
    public void run() {
        String threadName=Thread.currentThread().getName();
        int count=0;
        while(true){
            synchronized (baozi){
                count++;
                if(count>10){
                    break;
                }
                if(baozi.flag){
                    try {
                        baozi.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    System.out.println(threadName+"开始制作"+baozi.name);
                    baozi.flag=true;
                    baozi.notify();
                }
            }
        }
    }
}








public class ThreadTest {
    public static void main(String[] args) {
        Baozi baozi=new Baozi();
        baozi.name="韭菜鸡蛋包子";
        baozi.flag=true;



        Chihuo ch=new Chihuo("猪八戒",baozi);
        Zaocandian zcd=new Zaocandian("逍遥镇",baozi);


        zcd.start();
        ch.start();
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值