ArrayBlockingQueue

概述

ArrayBlockingQueue是采用数组实现的有界阻塞线程安全队列。如果向已满的队列继续塞入元素,将导致当前的线程阻塞。如果向空队列获取元素,那么将导致当前线程阻塞。

实现原理

1、属性
	// 存放元素的数组
    final Object[] items;
    // 提取数组元素的下标
    int takeIndex;
    // 往数组中添加元素的下标 
    int putIndex;
    // 队列中元素的数量
    int count;
    // 可重入锁
    final ReentrantLock lock;
    // 取元素的等待队列
    private final Condition notEmpty;
    // 添加元素的等待队列
    private final Condition notFull;

2、构造器
    public ArrayBlockingQueue(int var1) {
        this(var1, false);
    }

    public ArrayBlockingQueue(int var1, boolean var2) {
        this.itrs = null;
        if (var1 <= 0) {
            throw new IllegalArgumentException();
        } else {
            this.items = new Object[var1];
            this.lock = new ReentrantLock(var2);
            this.notEmpty = this.lock.newCondition();
            this.notFull = this.lock.newCondition();
        }
    }

    public ArrayBlockingQueue(int var1, boolean var2, Collection<? extends E> var3) {
        this(var1, var2);
        ReentrantLock var4 = this.lock;
        var4.lock();

        try {
            int var5 = 0;

            Object var7;
            try {
                for(Iterator var6 = var3.iterator(); var6.hasNext(); this.items[var5++] = var7) {
                    var7 = var6.next();
                    checkNotNull(var7);
                }
            } catch (ArrayIndexOutOfBoundsException var11) {
                throw new IllegalArgumentException();
            }

            this.count = var5;
            this.putIndex = var5 == var1 ? 0 : var5;
        } finally {
            var4.unlock();
        }

    }

创建ArrayBlockingQueue队列的时候,需要指定数组的大小,同时采用的是非公平锁的机制。

3、核心方法
public interface BlockingQueue<E> extends Queue<E> {
	// 将给定元素设置到队列中,如果设置成功返回true, 否则返回false。
	// 如果是往限定了长度的队列中设置值,推荐使用offer()方法。
    boolean add(E var1);
    
	// 将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,
	// 否则抛出空指针异常。
    boolean offer(E var1);

	// 将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,
	// 直到队列中有多余的空间。
    void put(E var1) throws InterruptedException;

	// 将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.
    boolean offer(E var1, long var2, TimeUnit var4) throws InterruptedException;

	// 从队列中获取值,如果队列中没有值,线程会一直阻塞,
	// 直到队列中有值,并且该方法取得了该值。
    E take() throws InterruptedException;

	// 在给定的时间里,从队列中获取值,时间到了直接调用普通的poll方法,
	// 为null则直接返回null。
    E poll(long var1, TimeUnit var3) throws InterruptedException;

	// 获取队列中剩余的空间。
    int remainingCapacity();

	// 从队列中移除指定的值。
    boolean remove(Object var1);

	// 判断队列中是否拥有该值。
    boolean contains(Object var1);

	// 将队列中值,全部移除,并发设置到给定的集合中
    int drainTo(Collection<? super E> var1);

	// 指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中。
    int drainTo(Collection<? super E> var1, int var2);
}

ArrayBlockQueue与LinkedBlockQueue的对比

不同点

1、存储,获取数据方式不同
ArrayBlockQueue是基础数组进行存储的,而LinkedBlockQueue是基础Node节点进行链式存储的。
LinkedBlockQueue在高并发的时候,可以进行往队列中边存数据,边取数据。

2、生产,消费使用的锁是不一样的
ArrayBlockQueue生产,消费都是使用同一个锁;LinkedBlockQueue生产,消费是不同锁。

3、初始化的大小不同
ArrayBlockQueue必须指定初始化大小。而LinkedBlockQueue可以不默认指定,创建的是一个MAX.Interger_value大小的队列。

相同点

1、默认获取锁的方式是一样的,都是非公平锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值