自定义阻塞队列

自定义阻塞队列

这个自定义阻塞队列基本就是jdk阻塞队列的实现

public class MyBlockQueue<E> {
    /**
     * 锁 保证并发安全
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 队列元素
     */
    private final Object[] items;

    /**
     * 取元素的下标
     */
    private int takeIndex;

    /**
     * 放元素的下标
     */
    private int putIndex;

    /**
     * 队列中元素的个数
     */
    private int count;

    /**
     * 用于队列空的时候阻塞
     */
    private Condition isEmpty = lock.newCondition();

    /**
     * 用于队列满的时候阻塞
     */
    private Condition isFull = lock.newCondition();

    public MyBlockQueue(){
        this(16);
    }

    public MyBlockQueue(int len) {
        // 队列长度不能小于0
        if (len < 0)
            throw new IllegalArgumentException("param is illegal");
        this.items = new Object[len];
    }

    public void put(E e) throws InterruptedException {
        // 加锁
        lock.lock();
        try{
            // 当队列满的时候线程阻塞
            while (count == items.length)
                isFull.await();
            items[putIndex] = e;
            // 判断队列是否插完,是的话就开始从第一个开始插
            if (++putIndex == items.length)
                putIndex = 0;
            // 元素个数加1
            count++;
            // 每插入一个元素就要唤醒阻塞在isEmpty上的线程
            isEmpty.signal();
            System.out.println(Thread.currentThread().getName() + ":放入元素,当前队列中有元素:" + count + "个");
        }finally {
           lock.unlock();
        }
    }

    public E take() throws InterruptedException {
        lock.lock();
        try{
            // 队列为空的时候阻塞
            while (count == 0)
                isEmpty.await();
            E item = (E)items[takeIndex];
            items[takeIndex] = null;
            // 元素个数减1
            count--;
            // 当takeIndex和数组长度相等的时候证明数组中元素已经取完
            if (++takeIndex == items.length)
                takeIndex = 0;
            // 保证下次取的时候数组不越界
            if (takeIndex > 0) takeIndex--;
            // 每获取一个线程就要唤醒阻塞在isFull上的线程
            isFull.signal();
            System.out.println(Thread.currentThread().getName() + ":取出元素,当前队列中有元素:" + count + "个");
            return item;
        }finally {
            lock.unlock();
        }
    }

    /**
     * 获取队列中元素个数
     * @return
     */
    public int getCount() {
        return count;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值