【经典】实现一个阻塞队列

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BlockingQueue<T> {

    /**
     * 对象池
     */
    private Object[] objs;

    /**
     * 容量
     */
    private int capacity = DEFAULT_CAPACITY;

    /**
     * 存元素的索引
     */
    private int putIndex = 0;

    /**
     * 取元素的索引
     */
    private int takeIndex = 0;

    /**
     * 元素个数
     */
    private int curLen = 0;

    /**
     * 并发锁
     */
    private Lock lock = new ReentrantLock();

    /**
     * 队列有元素
     */
    private Condition notNullCondition = lock.newCondition();

    /**
     * 队列有空间
     */
    private Condition notFullCondition = lock.newCondition();

    /**
     * 默认容量大小
     */
    private static final int DEFAULT_CAPACITY = 100;

    public BlockingQueue(int capacity) {
        if (capacity > 0) {
            this.capacity = capacity;
        }

        objs = new Object[this.capacity];
    }

    public void push(T obj) throws InterruptedException {
        try {
            lock.lock();

            // 容量已满,阻塞等待
            while (curLen == capacity) {
                System.out.println("Queue is full...");
                notFullCondition.await();
            }

            // 放置元素
            objs[putIndex] = obj;
            curLen++;

            // 索引更新
            putIndex++;
            if (putIndex >= capacity) {
                putIndex = 0;
            }

            // 通知消费者线程
            notNullCondition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public T poll() throws InterruptedException {
        Object obj;
        try {
            lock.lock();

            // 队列未空,阻塞等待
            while (curLen == 0) {
                System.out.println("Queue is empty...");
                notNullCondition.await();
            }

            // 获取元素
            obj = objs[takeIndex];
            curLen--;

            // 索引更新
            takeIndex++;
            if (takeIndex >= capacity) {
                takeIndex = 0;
            }

            // 通知生产者线程
            notFullCondition.signalAll();
        } finally {
            lock.unlock();
        }
        return (T) obj;
    }

    public static void main(String args[]) throws InterruptedException {
        BlockingQueue queue = new BlockingQueue(5);

        // 正常的入队、出队
        queue.push(1);
        System.out.println(queue.poll());
        queue.push(2);
        System.out.println(queue.poll());
        queue.push(3);
        System.out.println(queue.poll());

        // 持续入队
        queue.push(1);
        queue.push(2);
        queue.push(3);
        queue.push(4);
        queue.push(5);
        // 这里会阻塞
        // queue.push(6);

        // 持续出队
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        // 这里会阻塞
        // System.out.println(queue.poll());
    }

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值