• 写一个简单的阻塞队列


    给定一个(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,有点粗心了;

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

  • 相关阅读:
    linux常见错误1 -> E: 无法获得锁 /var/lib/apt/lists/lock open
    std::ostringstream用法浅析
    (译)C++11中的Move语义和右值引用
    C++11学习笔记(1) Rangebased for loop
    (转)Linux 下压缩与解压.zip和.rar及.7z文件
    (转)linux 查看当前用户及用户所属组别
    ubuntu 源码编译安装cmake2.8.10.2
    开始自学H5前端第一天
    自学H5第二天
    顶部滚动菜单栏
  • 原文地址:https://www.cnblogs.com/SpaceKiller/p/12536109.html
Copyright © 2020-2023  润新知