写一个简单的阻塞队列

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

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

 

posted @ 2020-03-21 01:30  我是白小白  阅读(552)  评论(0编辑  收藏  举报