zoukankan      html  css  js  c++  java
  • java并发编程工具类JUC第二篇:ArrayBlockingQueue

    ArrayBlockingQueueBlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素。这里的“有界”是指存储容量存在上限,不能无限存储元素。在同一时间内存储容量存在着一个上限值,这个上限制在初始实例化的时候指定,之后便不能修改了。

    ArrayBlockingQueue内部采用FIFO (First In, First Out)先进先出的方法实现队列数据的存取,队首的元素是在队列中保存时间最长的元素对象,队尾的元素是在队列中保存时间最短的元素对象。

    下面的代码说明如何初始化一个ArrayBlockingQueue,并向其中添加一个对象:

    BlockingQueue queue = new ArrayBlockingQueue(1024);
    queue.put("1");   //向队列中添加元素
    Object object = queue.take();   //从队列中取出元素
    

    BlockingQueue可以通过泛型来限定队列中存储数据的类型,下面的代码以String为泛型,表示该队列只能存储String类型。

    BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1024);
    queue.put("1");
    String string = queue.take();
    

    实现一个生产消费的实例

    在前面的文章中我们曾经讲过:BlockingQueue经常被用于生产消费的缓冲队列。下面我们就使用ArrayBlockingQueue来真正的实现一个生产消费的例子。

    BlockingQueueExample开启两个独立线程,一个是Producer生产者线程,负责向队列中添加数据;另一个是Consumer消费者线程,负责从队列中取出数据进行处理。

    public class BlockingQueueExample {
    
        public static void main(String[] args) throws Exception {
            //使用ArrayBlockingQueue初始化一个BlockingQueue,指定容量的上限为1024
            BlockingQueue queue = new ArrayBlockingQueue(1024);
            
            Producer producer = new Producer(queue);  //生产者
            Consumer consumer = new Consumer(queue);  //消费者
    
            new Thread(producer).start();  //开启生产者线程
            new Thread(consumer).start();  //开启消费者线程
    
            Thread.sleep(4000);
        }
    }
    
    

    Producer为生产者,每隔10秒钟使用put()方法向队列中放入一个对象,放入三次。在这10秒的间隔内,队列数据被消费者取走之后将导致消费者线程阻塞。

    public class Producer implements Runnable{
    
        protected BlockingQueue queue = null;
    
        public Producer(BlockingQueue queue) {
            this.queue = queue;
        }
    
        public void run() {
            try {
                queue.put("1");
                Thread.sleep(10000);
                queue.put("2");
                Thread.sleep(10000);
                queue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    下面的代码是消费者类Consumer,它从队列中获取待处理的元素对象,并调用System.out将其打印出来。

    public class Consumer implements Runnable{
    
        protected BlockingQueue queue = null;
    
        public Consumer(BlockingQueue queue) {
            this.queue = queue;
        }
    
        public void run() {
            try {
                System.out.println(queue.take());
                System.out.println(queue.take());
                System.out.println(queue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    上面的代码打印结果是每隔10秒打印一次,因为其中take()方法在队列内没有元素可以取到的时候,会阻塞当前的消费者线程,让其处于等待状态,这个方法我们在上一节介绍BlockingQueue的时候就已经进行过说明。

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    线程循环的故事
    代码质量
    代码质量控制之异常控制
    面对象静态结构描述方法
    解决maven下载依赖包,pom文件错误问题
    Spring学习笔记
    java编程命名规范
    powershell使用
    vert.x中future的简单使用
    idea调整import包的顺序
  • 原文地址:https://www.cnblogs.com/zimug/p/14831660.html
Copyright © 2011-2022 走看看