zoukankan      html  css  js  c++  java
  • JAVA多线程经典问题 -- 生产者 消费者 同步队列实现方法

    在JAVASE5 中的java.util.concurrent.BlockingQueue支持,BlockingQueue是一个接口但是我们通常可以使用LinkedBlockingQueue,它是一个无界的队列,当然我们还可以使用ArrayBlockingQueue,它拥有固定的尺寸,因此我们可以在他被阻塞之前放入有限的元素。

    当消费者试图从队列中获取对象时,如果队列为空,那么这些队列还可以挂起消费者任务,多么神奇的功能,那么当队列中有足够的元素可以供消费者获取,那么他可以回复消费者任务,比使用一些让人难理解的notifyAll wait要简单,并且可靠很多。简单写了两句

    class Product {
        private final int orderNum;
    
        public Product(int orderNum) {
            this.orderNum = orderNum;
        }
    
        public String toString() {
            return "Product" + orderNum;
        }
    }
    
    class Producter implements Runnable {
        private MainQueue main;
    
        public Producter(MainQueue main) {
            this.main = main;
        }
    
        public void run() {
            Product product = new Product(new Random().nextInt(100));
            //向队列插入一个元素 ,此时consumer任务是获取不了当前这个队列的所即他读取不了里面的数据
            main.queue.add(product);
            System.out.println("the Producter put the " + product
                    + " in to the queue");
        }
    }
    
    class Consumer implements Runnable {
        private MainQueue main;
        public Consumer(MainQueue main) {
            this.main = main;
        }
        public void run() {
            while (main.queue.size() > 0) {
                Product product = null;
                try {
                    //读队列中的一个元素,此时product任务写不进去元素
                    product = main.queue.take();
                    System.out.println("the Consumer get the" + product
                            + " from the quene");
                } catch (InterruptedException e) {
                    System.out.println("Consumer interrupted!");
                }
            }
        }
    
    }
    
    public class MainQueue {
        //这是一个同步队列 它只允许一个任务插入或者删除元素 LinkedBlockingQeque是一个无界的队列
        BlockingQueue<Product> queue = new LinkedBlockingDeque<>();
        Producter producter = new Producter(this);
        Consumer consumer = new Consumer(this);
    
        public MainQueue() {
            for (int i = 0; i < 10; i++) {
                new Thread(producter).start();
            }
            for (int i = 0; i < 10; i++) {
                new Thread(consumer).start();
            }
        }
    
        public static void main(String[] args) {
            new MainQueue();
        }
    }

    看是不是很简单,运行结果如下:

    the Producter put the Product91 in to the queue
    the Producter put the Product50 in to the queue
    the Producter put the Product72 in to the queue
    the Producter put the Product46 in to the queue
    the Producter put the Product92 in to the queue
    the Producter put the Product91 in to the queue
    the Producter put the Product52 in to the queue
    the Producter put the Product48 in to the queue
    the Producter put the Product41 in to the queue
    the Consumer get theProduct91 from the quene
    the Consumer get theProduct52 from the quene
    the Producter put the Product72 in to the queue
    the Consumer get theProduct92 from the quene
    the Consumer get theProduct50 from the quene
    the Consumer get theProduct72 from the quene
    the Consumer get theProduct72 from the quene
    the Consumer get theProduct91 from the quene
    the Consumer get theProduct48 from the quene
    the Consumer get theProduct41 from the quene
    the Consumer get theProduct46 from the quene

    有不足之处和错误之处,请留言,本人虚心请教。

  • 相关阅读:
    android listview 圆角的实现方案,模仿Iphone的UITableView
    在android编程中插入背景图片
    iOS开发UI篇—UIPickerView控件简单介绍
    iOS开发UI篇章 15-项目中的常见文件
    iOS开发UI篇章之通知中心(NSNotificationCenter)
    iOS开发UI篇章之应用管理的九宫格坐标计算
    iOS开发UI篇章之-Button基础
    Xcode-Run和快捷键
    Css基础-介绍及语法
    CSDN首页> 移动开发 直接拿来用!最火的Android开源项目(完结篇)
  • 原文地址:https://www.cnblogs.com/zm112358/p/3231365.html
Copyright © 2011-2022 走看看