多线程-生产者消费者模型

发布时间:2024年01月08日

一、基本信息

1、场景介绍:厨师和吃货的例子,吃货吃桌子上的面条,吃完让厨师做,厨师做完面条放桌子上,让吃货吃,厨师如果发现桌子上有面条,就不做,吃货发现桌子上没有面条就不吃。

2、线程实现基本步骤:

  1. 循环
  2. 同步代码块
  3. 循环退出条件
  4. 循环没有退出时,业务代码的实现

二、代码实现?

桌子类:

public class Desk {
    //食物状态
    public static int status = 0;
    //锁
    public static Object lock = new Object();
    //面条剩余数量
    public static int count = 5;
}

厨师类:

/**
 * 厨师做饭线程
 */
public class Cookie extends Thread{
    /**
     * 多线线程实现的基本步骤:
     * 1、循环
     * 2、同步代码块
     * 3、循环的退出条件
     * 4、未退出时的业务代码逻辑
     */

    /**
     * 厨师的业务逻辑
     * 1、判断桌子上有没有面条
     * 2、有面条就等待;没有面条就做面条,并且唤醒等待的吃货吃面条
     */

    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                //判断面条数量
                if (Desk.count == 0) {
                    break;
                }
                //判断桌子上是否有面条
                if (Desk.status == 1){
                    //有面条时,就等待
                    //这里需要用锁对象调用等待方法,目的是为了绑定锁和线程
                    try {
                        Desk.lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    //没有面条就要做面条
                    System.out.println(getName() + "做了一碗面条");
                    //改状态,表示面条做好了
                    Desk.status = 1;
                    //唤醒吃货吃面条
                    Desk.lock.notifyAll();
                }
            }
        }
    }
}

吃货类:

/**
 * 吃货
 */
public class Foodie extends Thread {
    /**
     * 多线线程实现的基本步骤:
     * 1、循环
     * 2、同步代码块
     * 3、循环的退出条件
     * 4、未退出时的业务代码逻辑
     */

    /**
     * 吃货的业务逻辑
     * 1、判断桌子上有没有面条
     * 2、有面条就吃;没有面条就等待,并且唤醒等待的厨师做面条
     */
    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                //判断面条数量
                if (Desk.count == 0) {
                    break;
                } else {
                    //判断桌子上是否有面条
                    if (Desk.status == 1) {
                        Desk.count--;
                        System.out.println(getName() + "吃了一碗面条");
                        System.out.println(getName() + "还能吃" + Desk.count + "碗面条");
                        Desk.status = 0;
                        Desk.lock.notifyAll();
                    }else {
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

?测试类:

public class TestCookie {
    public static void main(String[] args) {
        Cookie cookie = new Cookie();
        Foodie foodie = new Foodie();

        cookie.setName("厨师");
        foodie.setName("吃货");

        cookie.start();
        foodie.start();
    }
}

运行结果:

文章来源:https://blog.csdn.net/qq_42251944/article/details/135461670
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。