zoukankan      html  css  js  c++  java
  • 写一个简单的阻塞队列

    给定一个(ArrayList)将其改写成一个简单的阻塞队列,要求拥有put和get方法,以及getSize方法,能够支持多个生产者和多个消费者线程拥塞调用。

    1】使用synchronized锁或ReentrantLock锁实现

    1】使用Object的wait、notify、notifyAll来实现

    基本思路:使用put方法向容器中添加元素,使用get方法从容器中取出元素,在使用put方法添加元素的时候进行判断,如果容器已经满了,此时调用wait()方法,使用添加线程阻塞,等待消费线程取出元素,腾出容器空间后才能再向其中添加元素,同理当使用get方法获取元素的时候,如果容器已经为空,此时要调用wait()方法,使得取出元素线程阻塞,等待添加线程添加元素,容器不为空时才能再从容器中取出元素

    public class MyArrayBlockingQueue<T>{
        /*
         * 调用无参构造方法,阻塞队列的默认长度
         */
        public static final int SIZE_VALUE=10;
        /*
         * 队列的容器存放队列的元素
         */
        public final List<T> lists=new ArrayList<>();
        /*
         * 队列的最大容量
         */
        private final int maxSize;
        /*
         * 队列当前元素个数
         */
        private int size=0;
        
        public MyArrayBlockingQueue() {
            super();
            this.maxSize=SIZE_VALUE;
        }
    
        /**
         * 带参构造方法,创建时可设定队列最大元素
         * @param maxSize 队列最大元素数量
         */
        public MyArrayBlockingQueue(int maxSize) {
            this.maxSize = maxSize;
        }
        /**
         * 生产者向容器中插入元素时调用的方法
         * @param t 传入队列中的元素
         * @throws InterruptedException 向上抛出线程中断的异常
         */
        public synchronized void put(T t) throws InterruptedException {
            while (lists.size()==maxSize) {
                System.out.println("队列中元素数量为"+maxSize+"个,队列进入则阻塞状态");
                this.wait();
            }
            lists.add(t);
            ++size;
            System.out.println("生产元素中元素数量size:"+size+" ");
            this.notifyAll();//唤醒消费线程进行消费
        }
        /**
         * 消费者从容器中取元素时调用的方法
         */
        public synchronized T get() {
            T t=null;
            while(lists.size()==0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            t=lists.get(0);
            lists.remove(0);
            --size;
            System.out.println("消费容器中元素数量为size:"+size+" ");
            this.notifyAll();//唤醒生产线程进行生产
            return t;
        }
        /**
         * 队列当前元素数量
         */
        public int getSize() {
            return size;
        }
    }

    测试结果:

     第一次测试,发现取出的数据都是0;后来检查了一下,是在get方法中,忘记将取出的元素remove掉了,导致取到的值都是0,有点粗心了;

    使用其他的集合累的话,也可以转换成阻塞队列,大家也可以试一试

  • 相关阅读:
    ArrayList removeRange方法分析
    LinkedHashMap源码分析(基于JDK1.6)
    LinkedList原码分析(基于JDK1.6)
    TreeMap源码分析——深入分析(基于JDK1.6)
    51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划
    51 NOD 1049 最大子段和 动态规划 模板 板子 DP
    51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
    8月20日 训练日记
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/SpaceKiller/p/12536109.html
Copyright © 2011-2022 走看看