java实现循环队列(生产者消费者)

顺序队列的问题:

我们在实现顺序栈时使用头指针“front”和尾指针“rear”分别进行出队和入队操作,但普通的队列如上图所示,会发生“假溢出”现象,所以我们通常将数组弄成一个环状,即队头和队尾相连,这样就形成了“循环队列”,同时也解决了“假溢出”现象。循环队列是改进版的顺序队列。

对于普通队列的push或pop我们只需要对尾指针或头指针进行自增操作即可,但是循环队列我们就不能单纯的进行自增,当front或rear=maxSize-1时我们就不能进行自增操作了,比如一个队列尾长度为4的数组datas[4],那么当front或rear需要在0,1,2,3之间进行循环“推进”,以此达到循环队列的效果。所以我们可以使用rear = (rear+1)%maxSize ;front = (front+1)%maxSize ;公式进行指针计算。

需要注意的是:队空状态的条件为:front = rear。而如果整个队列全部存满数据那么,队满的条件也是front = rear;所以循环队列需要损失一个存储空间,如下图

 

 

    public class myQueue {
        public int size = 10;    // 队列大小
        public int count = 0;    // 计数
        public int datas[];    
        public int front;        // 头指针
        public int rear;         // 尾指针

        public myQueue(int size) {
            this.size = size;
            datas = new int[10];
            count = 0;
            front = 0;
            rear = 0;
        }

        public boolean enqueue(int data) {
            if (isFull()) {
                return false;
            }
            datas[rear] = data;
            rear = (rear + 1) % size;
            count++;
            return true;
        }

        public int dequeue() throws Exception {
            if (isEmpty()) {
                throw new Exception("empty");
            }
            int data = datas[front];
            front = (front + 1) % size;
            count--;
            return data;
        }

        /**
         * 循环队列空队和满队条件都是front == rear解决该问题有几种判断如下
         * 1.循环队列损失一个存储空间
         * 2.设计一个计数器count,统计队列中的元素个数。此时,队列满的判断条件为:count > 0 && rear == front ;队列空的判断条件为count == 0。
         *
         * @return
         */
        public boolean isFull() {
            return (rear + 1) % size == front;
        }

        public boolean isEmpty() {
            return front == rear;
        }

        public int getFront() throws Exception {
            if (!isEmpty()) {
                throw new Exception("empty");
            }
            return datas[front];
        }
    }



    class producer implements Runnable {

        @Override
        public void run() {
            while (true) {
                synchronized (myQueue) {
                    while (myQueue.isFull()) {
                        myQueue.notify();
                        Log.i(TAG, "run: 队满!");
                        try {
                            myQueue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    myQueue.enqueue(1);
                    Log.i(TAG, "run: 生产1,队列长度: " + myQueue.count);
                    myQueue.notify();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    class consumer implements Runnable {

        @Override
        public void run() {
            while (true) {
                synchronized (myQueue) {
                    while (myQueue.isEmpty()) {
                        myQueue.notify();
                        Log.i(TAG, "run: 队空!");
                        try {
                            myQueue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        myQueue.dequeue();
                        Log.i(TAG, "run: 消费1,队列长度: " + myQueue.count);
                        myQueue.notify();
                        Thread.sleep(500);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值