Java阻塞队列详解

1.什么是阻塞队列

阻塞队列--BlockingQueue,它是一个接口,

public interface BlockingQueue<E> extends Queue<E>

BlcokingQueue继承了Queue接口,是队列的一种,Queue和BlockingQueue都是在Java5中加入的,BlockingQueue是线程安全的,我们在很多场景下都可以利用线程安全的队列来优雅地解决我们业务自身的线程安全问题。
主要并发队列关系图

上图展示了Queue最主要的实现类,可以看出Java提供的线程安全的队列(也成为并发队列)主要分为阻塞队列和非阻塞队列俩大类。

  • 阻塞队列的典型例子就是BlockingQueue接口的实现类,主要有6种实现:ArrayBlcokingQueue,LinkedBlockingQueue,SynchronousQueue,DelayQueue,PriorityBlockingQueue和LinkedTransherQueue,它们各自有不同不同的特点。
  • 非阻塞并发队列最典型的就是ConcurrentLinkedQueue,这个类不会让线程阻塞,利用CAS保证了线程安全。
  • 从上图还可以看到Deque,就是双端队列,双端队列从头和尾都能添加和删除元素,而普通的Queue只能从一端进入,另一端出去。这是Queue和Deque最主要的区别,其它方面基本都差不多。

2.阻塞队列的特点

阻塞队列的特点就是阻塞两个字,哈哈哈哈。像是废话。阻塞功能使得生产者和消费者两端的能力得以平衡,当有任何一端速度过快时,阻塞队列便会把过快的速度降下来。最重要的两个方法:take()和put();
take()
take方法的功能是获取并移除队列的头节点,通常在队列里有数据的时候是可以正常移除的,当队列里无数据,则阻塞,直到队列里面有数据。一旦有数据了,就立刻解除阻塞状态,并且获取到数据 put()
put方法插入元素时,如果队列没有满可以正常插入,如果队列满了,则阻塞,直到队列里面有了空闲空间,就会消除阻塞状态,并把数据添加进去。

阻塞队列容量问题

阻塞队列分为两种有界和无界。无界队列意味着里面可以容纳非常多的元素,例如LinkedBlcokingQueue的上限是Integer.MAX_VALUE。学过Java的人都知道这个数其实挺大的。但有界队列例如ArrayBlockingQueue如果队列满了,也不会扩容。

3.阻塞队列常用方法

在阻塞队列中有很多方法,而且都非常相似,这里我把常用的8个方法总结了一下以添加、删除为主。主要分为三类:

  • 抛出异常:add、remove、element
  • 返回结果但是不抛出异常:offer、poll、peek、
  • 阻塞:take、put、

3.1 抛出异常:add、remove、element

add方法是往队列里面添加一个元素,如果队列满了,就会抛出异常来提示我们队列已满。

public static void main(String[] args) {
    BlockingQueue<Integer> blockingQueue=new ArrayBlockingQueue<>(2);
    blockingQueue.add(1);
    blockingQueue.add(1);
    blockingQueue.add(1);
}

这里我们指定队列容量为2,并且尝试加入3个值。超过了容量上限就会报IllegalStateException的错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值