多线程编程-三

阻塞队列- 基础知识

BlockingQueue 的核心方法

放入数据:

  • offer(anObject): 表示如果可能的话,将 anObject 加到 BlockingQueue 里。即如果 BlockingQueue 可以容纳,则返回 true,否则返回 false 。(本方法不阻塞当前执行方法的线程)

  • offer(E o,long timeout,TimeUnit unitz): 可以设定等待时间。如果在指定的时间内还不能往队伍中加入 BlockingQueue,则返回失败。

  • put(anObject): 将 anObject 加到 BlockingQueue 里,如果 BlockingQueue 没有空间,则调用此方法的线程被阻断,直到 BlockingQueue 里面有空间再继续。

获取数据:

  • poll(long timeout,TimeUnit unit): 从 BlockingQueue 中取出一个队首的对象。如果在指定时间内,队列一旦有数据可取,则立即返回队列中的数据:否则知道时间超时还没有数据可取,返回失败。

  • take(): 取走 BlockingQueue 里排在首位的对象。若 BlockingQueue 为空,则阻断进入等待状态,知道 BlockingQueue 有新的数据被加入。

  • drainTo(): 一次性从 BlockingQueue 获取所有可用的数据对象(还可以指定获取数据的个数)。通过该方法,可以提升获取数据的效率:无须多次分批加锁或释放锁。

Java中的7个阻塞队列

  • ArrayBockingQueue: 由数据结构组成的有界阻塞队列。
  • LinkedBlockingQueue: 由链表结构组成的有界阻塞队列。
  • PriorityBlockingQueue: 支持优先级排序的无界阻塞队列。
  • DelayQueue: 使用优先级队列实现的无界阻塞队列。
  • SynchronousQueue: 不存储元素的阻塞队列。
  • LinkedTransferQueue: 由链表结构组成的无界阻塞队列。
  • LinkedBlockingDeque: 由链表结构组成的双向阻塞队列。
ArrayBlockingQueu 和 LinkedBlockingQueue

ArrayBlockingQueu:是用数组实现的有界阻塞队列,并按照先进先出(FIFO)的原则对元素进行排序。

	//第一个参数是容量    第二个参数是是否要保证线程的公平地访问队列(默认是false)
    ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(200,true);                                          

LinkedBlockingQueue: 是基于链表的阻塞队列,同 ArrayBlockingQueu类似。
那他们区别在哪?

  • 队伍中锁的实现不同
    ArrayBlockingQueue 实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁。
    LinkedBlockingQueue 实现的队列中锁是分离的,即生产用的是 putLock,消费是 takeLock。

  • 在生产或消费是操作不同
    ArrayBlockingQueue 实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的。
    LinkedBlockingQueue 实现的队列中在生产和消费的时候,需要把枚举对象转换为 Node 进行插入或移除,会影响性能。

  • 队列大小初始化方式不同
    ArrayBlockingQueue 实现的队列中必须指定队列的大小
    LinkedBlockingQueue 实现的队列中可以不指定队列的大小,但是默认是 Integer.MAX_VALUE

一般情况下,在处理多线程间的生产者-消费者问题是,使用这两个就可以。

PriorityBlockingQueue

它是一个支持优先级的无界队列。默认情况下元素采取自然顺序升序排列。这里可以自定义实现 compareTo() 方法来指定元素进行排序规则;或者初始化 PriorityBlockingQueue 时,指定构造参数 Comparator 来对元素进行排序。但其不能保证同优先级元素的排序。

DelayQueue

它是一个支持延时获取元素的无界阻塞队列。队列使用 PriorityBlockingQueue 来实现。 队列中的元素必须实现 Delayed 接口。创建元素是,可以指定元素到期的时间,只有在元素到期时才能从队列中取走。

SynchronousQueue

它是一个不存储元素的阻塞队列。每个插入操作必须等待另一个线程的移除操作,同样任何一个移除操作都等待另一个线程的插入操作。

LinkedTransferQueue

它是一个有链表结构组成的无界阻塞 TransferQueue 队列。LinkedTransferQueue 实现一个重要的接口 TransferQueue 。该接口含有5个方法,其中有3个重要的方法。分别是:

  • transfer(E e):若当前存在一个正在等待获取的消费者线程,则立刻将元素传递给消费者;如果没有消费者在等待接受数据,就会将元素插入到队列尾部,并且等待进入阻塞状态,知道有消费者线程取走该元素。
  • tryTransfer(E e): 若当前存在一个正在等待获取的消费者线程,则立刻将元素传递给消费者;若不存在,则返回 false,并且不进入队列,这是一个不阻塞的操作。
  • tryTransfer(E e, long timeout, TimeUnit unit): 若当前存在一个正在等待获取的消费者线程,则立刻将元素传递给消费者;如果没有消费者在等待接受数据,就会将元素插入到队列尾部。若在指定的超时时间内元素未被消费者线程获取,则返回 false ;若在指定的超时时间内元素被消费者线程获取,则返回 true ;
LinkedBlockingDeque

它是一个有链表结构组成的双向阻塞队列。双向队列可以从队列的两端插入和移出元素,因此在多线程同时入队时,也就减少了一半的竞争。由于时双向的,因此 LinkedBlockingDeque 多了 addFirst、 addLast、 offerFirst、offerLast、peekFirst、peekLast 等方法,其中,以 First单词结尾的方法,表示插入、获取或移除双端队列的第一个元素;以 Last单词结尾的方法,表示插入、获取或移除双端队列的最后一个元素。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值