• Java简易版生产者消费者模型


    Java简易版生产者消费者模型

    一、概述

    一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程。当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完。

    需要注意的是,有可能出现,停止生产产品后,消费者还没未来得及消费生产者生产的最后一个产品,就结束消费,导致最后一个产品没有被消费。

    本例使用synchronize以及wait()、notify()实现简易版的线程者消费者模型。

    二、测试用例

    这里的产品用笔来演示,每只笔都有其编号code

    一共有四个类:分别是生产者类,产品类,消费者类,测试类

    image-20200531231046794

    产品

    package test.exception.producer_consumer_model;
    
    /*
    假设为产品为笔
     */
    
    public class Production {
        private String type = "";
        private String color = "";
        private long code = 0; // 产品编号
        private boolean isProduced = false; // 是否生产完成 初始状态为未生产状态
        private boolean isContinueProduce = true; // 是否停产该产品
    
        public void setContinueProduce(boolean continueProduce) {
            isContinueProduce = continueProduce;
        }
    
        public void setCode(long code) {
            this.code = code;
        }
    
        public Production(){
        }
    
        public boolean isContinueProduce() {
            return isContinueProduce;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public void setProduced(boolean produced) {
            isProduced = produced;
        }
    
        public boolean isProduced() {
            return isProduced;
        }
    
        @Override
        public String toString() {
            return color + type + "-" + code;
        }
    }
    

    生产者

    package test.exception.producer_consumer_model;
    
    public class Producer implements Runnable {
        private final Production pen;  // 产品
    
        public Producer(Production pen) {
            this.pen = pen;
        }
    
        // 生产
        public void produce() {
            long code = 0;
            while (this.pen.isContinueProduce()) {
                synchronized (this.pen) {
                    if (this.pen.isProduced()) {
                        try {
                            this.pen.wait(); // 等待消费者消费
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 开始生产
                    this.pen.setType("铅笔");
                    this.pen.setColor("蓝色");
                    this.pen.setCode(code++);
                    this.pen.setProduced(true);
                    System.out.println(this.pen + " is produced");
                    this.pen.notify();
                }
            }
            System.out.println("finish producing");
        }
    
    
        @Override
        public void run() {
            produce();
        }
    }
    

    消费者

    package test.exception.producer_consumer_model;
    
    public class Consumer implements Runnable {
        private final Production pen;
    
        public Consumer(Production pen) {
            this.pen = pen;
        }
    
        // 持续消费
        public void consumer() {
            while (this.pen.isContinueProduce()) {
                synchronized (this.pen) {
                    if (!this.pen.isProduced()) {
                        try {
                            this.pen.wait(); // 等待生产者生产
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                    System.out.println(this.pen + " is consumed"); // 使用
                    this.pen.setProduced(false); // 使用完后更新状态
                    this.pen.notify();
                }
            }
            // 确保停止生产后,能够使用最后生产的一支笔
            if (this.pen.isProduced()) {
                System.out.println(this.pen + " is consumed");
            }
    
            System.out.println("finish using");
        }
    
        @Override
        public void run() {
            consumer();
        }
    }
    

    主线程测试

    package test.exception.producer_consumer_model;
    
    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            Production pen = new Production();
            Consumer consumer = new Consumer(pen);
            Producer producer = new Producer(pen);
            new Thread(producer).start();  // 开启生产者线程
            new Thread(consumer).start();  // 开启消费者线程
    
            Thread.sleep(10000);
            pen.setContinueProduce(false);  // 10s后停止生产该类型的笔
        }
    }
    

    运行结果

    image-20200531232925276

  • 相关阅读:
    Linux学习笔记(第一章)
    C#中的抽象类有什么好处?究竟它是用来干事什么的呢?
    C#中的 增 、删、 改、 查功能
    在Visual C#中用ListView显示数据记录
    10.14JDBC之数据库连接池之C3P0
    10.19JDBC之使用C3P0连接池重新实现JDBCUtils方法
    10.12JDBC之DAO实现类的优化
    10.13JDBC之数据库连接池
    RhinoMock入门(3)——4种Mock类型
    wse说谈(3)——策略,用户令牌
  • 原文地址:https://www.cnblogs.com/main404/p/13022369.html
Copyright © 2020-2023  润新知