zoukankan      html  css  js  c++  java
  • java多线程-生产者消费者模式

    首先,谈到java多线程,不得不提的就是生产者和消费者模式,所谓生产者和消费者模式:生产者在生产商品的时候,消费者同时消费

    一、设计思路

    1、既然是同时运行,所以,肯定要用到多线程,用多个线程模拟生产者和消费者

    2、他们操作的产品一定是相同的,呀,又涉及到了资源共享,所以,又要用到线程锁

    3、但是单纯加上方法锁也可以,当产品不足时,或者产品过量时,不操作即可,但是会造成线程的空运行,资源的浪费,所以当生产者(或者消费者)存在这些问题时,就调用wait方法进入等待队列,另一方操作完成后,(notify)进行唤醒,完美!

    二、代码实现(此处用到是wait和notifyAll方法,ReentrantLock方法类似,无非就是lock和unlock,大家可以尝试):

    1、产品类:

    /**
     * 产品类
     */
    public class Product {
        public Product(String name) {
            this.name = name;
        }
    
        private String name;
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }

    2、产品池类:

    /**
     * 产品池
     */
    public class ProductPool {
        private List<Product> productList;
        private int maxNum;
        // 构造方法
        public ProductPool(int maxNum){
            // 用来存放所有的产品
            this.productList = new ArrayList<Product>();
            // 用来表示产品的最大数量
            this.maxNum = maxNum;
        }
    
        /**
         * 生产方法
         * @param product
         */
        public synchronized void push(Product product){
            // 判断是否已经达到最大长度,如果是,则进入等待队列
            if(this.productList.size() == maxNum){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.productList.add(product);
            // 唤醒其他线程
            this.notifyAll();
        }
    
        /**
         * 消费方法
         * @return
         */
        public synchronized Product pop(){
            // 判断是否已经没有产品可以消费,如果没有,则将线程放入等待队列
            if(this.productList.size() == 0){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 消费产品并且返回对应的产品
            Product product = this.productList.remove(0);
            this.notifyAll();
            return product;
        }

    3、生产者

    /**
     * 生产者
     */
    public class Productor extends Thread{
        private ProductPool productPool;
        // 采用构造方法,将产品池引入
        public Productor(ProductPool productPool){
            this.productPool = productPool;
        }
        @Override
        public void run(){
            while (true){
                // 随机生成生产的产品
                String name = (int)(Math.random()*100)+"号产品";
                Product product = new Product(name);
                productPool.push(product);
                System.out.println("The product is producting product......named "+product.getName());
            }
        }

    4、消费者

    /**
     * 消费者
     */
    public class Consumer extends  Thread{
        private ProductPool productPool;
        // 采用构造方法,将产品池引入
        public Consumer(ProductPool productPool){
            this.productPool = productPool;
        }
        @Override
        public void run() {
            while (true){
                // 消费产品,并且取出已经消费的产品
                Product product = this.productPool.pop();
                System.out.println("The consumer is consuming product......named "+product.getName());
            }
        }

    5、测试类

    /**
     * 生产者消费者测试类
     */
    public class Test {
        public static void main(String[] args) {
            // new 产品池
            ProductPool productPool = new ProductPool(10);
            // new 生产者和消费者
            Productor productor = new Productor(productPool);
            Consumer consumer = new Consumer(productPool);
            // 开启线程
            productor.start();
            consumer.start();
        }

    好啦,基于多线程的生产者和消费者的实现就是这些,欢迎业界大佬批评指正!

  • 相关阅读:
    数组练习1
    学习进度04
    求一个数组的最大子数组之和02
    求一个数组的最大子数组之和01
    学习进度03
    四则运算的功能添加版02
    第二周学习进度
    Right-BICEP 测试四则运算程序
    实现四则运算的功能添加版01
    本周实验PSP0 过程文档
  • 原文地址:https://www.cnblogs.com/mcjhcnblogs/p/13091982.html
Copyright © 2011-2022 走看看