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

1.1 线程间通信

**概念 :**多个线程在处理同一个资源,但是处理的线程任务不一样

比如说:荒木老师生产小面包,而Dio来吃面包 ,这个面包就是同一个资源,

然而 一个是生产 一个是吃,那么荒木老师和Dio之间就存在线程通信的问题。

当多个线程并发执行时,我们的CPU进行高速的切换随即切换线程。但是我们要做多个线程来完成同一个任务的时候,那么多线程之间需要一些协调通信。这就是为什么我们要处理线程之间的通信。

并且, 多个线程在操作同一份数据的时候,为了避免对同一共享变量的争夺,(自我理解:荒木老师在没有生产出小面包的时候 Dio就要吃)。

通过一定的手段使各个线程能有效的利用资源 这种手段叫做 等待唤醒机制

1.2 等待唤醒机制

在这里插入图片描述

因为不想再改面包 所以我们就让Dio吃包子吧

//包子属性
class BaoZi{
    
    
    /*
  * 有皮
  * 有馅
  * 对包子状态的判断
  * */
    String xian;
      String pi;
      boolean flag=false;
 }

//消费者
class Consumer implements Runnable{
    
    
    private  BaoZi baoZi;
    private  Lock lock;   //锁对象
    public Consumer(BaoZi baoZi, Lock lock) {
    
    
        this.baoZi = baoZi;
        this.lock = lock;
    }
    @Override
    public void run() {
    
    
       while (true){
    
    
           synchronized (lock){
    
    
               //判断有没有包子 (没有包子)
               if (baoZi.flag==false){
    
    
                   try {
    
    
                       lock.wait();
                   } catch (InterruptedException e) {
    
    
                       e.printStackTrace();
                   }
               }
               System.out.println("开始吃"+this.baoZi.pi+this.baoZi.xian+"的包子");
               //吃完包子后修改状态
               baoZi.flag=false;
               //吃完唤醒包子铺线程,生产包子 (饿了 ,来唤醒生产者)
               lock.notify();
               System.out.println("吃完了"+this.baoZi.pi+this.baoZi.xian+"的包子");
               System.out.println("============================================");
           }
       }
    }
}

//生产者
 class  Producer  implements Runnable{
    
    
    private  BaoZi baoZi;
    private  Lock lock;
public Producer (BaoZi baoZi, Lock lock) {
    
    
    this.baoZi = baoZi;
    this.lock = lock;
}
@Override
public void run() {
    
    
    int count=0;
    //让包子铺一直做包子
    while (true){
    
    
        synchronized (lock){
    
    
            //首先判断有没有包子    (一开始没有包子)
            if (baoZi.flag){
    
    
                try {
    
    
                    lock.wait();  //等待
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
            // wait之后的代码被消费者唤醒后执行,包子铺生产包子
            if (count%2==0){
    
    
                baoZi.pi="薄皮";
                baoZi.xian="牛肉大葱";
            }else {
    
    
                baoZi.pi="冰皮";
                baoZi.xian="韭菜鸡蛋";
            }
            count++;
            System.out.println("正在做"+baoZi.pi+baoZi.xian+"馅的包子");
            //包子正在做
            try {
    
    
                System.out.println("做包子中························");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            this.baoZi.flag=true;
            //唤醒吃包子的消费者
            lock.notify();
            System.out.println("做好了"+baoZi.pi+baoZi.xian+"馅的包子");
        }
    }
}
}
//主方法
public class P_CThreadTest {
    
    
    public static void main(String[] args) {
    
    
        BaoZi baoZi = new BaoZi();
        Lock lock = new ReentrantLock();
        new Thread(new Producer(baoZi,lock)).start();
        new Thread(new Consumer(baoZi,lock)).start();
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/agood_man/article/details/108246693