关于spring:java并发编程工具类JUC第一篇BlockingQueue阻塞队列

51次阅读

共计 4164 个字符,预计需要花费 11 分钟才能阅读完成。

Java BlockingQueue 接口 java.util.concurrent.BlockingQueue 示意一个能够存取元素,并且线程平安的队列。换句话说,当多线程同时从 JavaBlockingQueue中插入元素、获取元素的时候,不会导致任何并发问题(元素被插入屡次、解决屡次等问题)。

从 java BlockingQueue能够引申出一个概念:阻塞队列,是指队列自身能够阻塞线程向队列外面插入元素,或者阻塞线程从队列外面获取元素。比方:当一个线程尝试去从一个 空队列 外面获取元素的时候,这个线程将被阻塞直到队列内元素数量不再为空。当然,线程是否会被阻塞取决于你调用什么办法从 BlockingQueue 获取元素,有的办法会阻塞线程,有的办法会抛出异样等等,下文咱们会具体介绍。

一、BlockingQueue 接口实现类

本文不会去介绍如何本人实现 BlockingQueue 接口,JUC 曾经为咱们做好了相干的一些接口实现类。
BlockingQueue是一个 java 接口,当咱们须要应用阻塞队列的时候,能够应用它的实现类。java.util.concurrent包外面有如下的一些实现类实现了 BlockingQueue 接口。

  • ArrayBlockingQueue
  • DelayQueue
  • LinkedBlockingQueue
  • LinkedBlockingDeque
  • LinkedTransferQueue
  • PriorityBlockingQueue
  • SynchronousQueue

在本文以及后续的文章中,会顺次为大家介绍这些实现类的作用及应用场景,期待您的关注。

二、BlockingQueue 利用场景介绍

BlockingQueue通常被利用在一个线程生产对象放入队列,与此同时另一个线程生产队列内的对象的场景下。上面的这张图阐明了应用场景:

生产者线程一直的生产新的对象,并将他们插入到BlockingQueue,直到队列中 object 的数量达到队列存储容量的下限。也就是说当队列中对象达到容量下限的时候,生产者线程将被阻塞,不能再向队列中插入新的对象。生产者线程将放弃阻塞期待状态,直到消费者线程从队列中拿走 Object,让队列有空余地位放入新的对象。

消费者线程一直的从 BlockingQueue 取出对象并将其进行解决。如果消费者线程尝试从一个空队列中获取一个对象,消费者线程将被阻塞处于期待状态,直到生产者向队列中放入一个新的对象。

所以 BlockingQueue 常常被用于生产生产的缓冲队列,如果你不想用分布式的或者中间件音讯队列(redis、kafka)等(因为对于一个小性能会减少比拟大的独立中间件运维老本),BlockingQueue 能够能是一个备选的选项。

2.1.BlockingQueue 办法介绍

JavaBlockingQueue 提供了四组不同的办法用于向队列中插入、移除、查看队列中蕴含某一元素对象。每一组办法在被调用之后的响应行为上有所不同,如下:

抛出异样返回特定值阻塞后始终期待阻塞后期待超时
插入对象add(o)offer(o)put(o)offer(o, timeout, timeunit)
移除对象remove(o)poll()take()poll(timeout, timeunit)
查看对象存在element()peek()

下面的办法的四种行为别离的含意是

  1. 抛出异样: 如果调用办法后不能立刻响应后果(空队列或满队列),则抛出异样。
  2. 返回特定值: 如果调用办法后不能立刻响应后果(空队列或满队列),则返回特定的值(通常是 true/false),true 示意办法执行胜利,否则示意办法执行失败。
  3. 阻塞后始终期待: 如果调用办法后不能立刻响应后果(空队列或满队列),该办法将被阻塞始终处于期待状态。
  4. 阻塞后期待超时: 如果调用办法后不能立刻响应后果(空队列或满队列),该办法将在肯定工夫范畴内被阻塞期待,也就是在超时工夫范畴内阻塞。当超出超时工夫之后,办法线程将不再阻塞,而是返回一个特定的值(通常是 true/false),true 示意办法执行胜利,否则示意办法执行失败。

另外,BlockingQueue队列不容许向其外部插入 null,如果你向队列中插入 null,将会引发 NullPointerException 异样。
个别的队列都是从队首放入对象,从队尾获取对象,BlockingQueue不仅反对从队首队尾操作数据对象,还反对从队列中其余任何地位操作数据。比方:你曾经向队列中放入一个对象并期待解决,然而出于某些非凡起因心愿将这个对象从队列中删除掉。你能够调用 remove(o) 办法来删除队列中的一个特定的 o 对象。当然咱们的程序不能经常性的这样做,因为队列这种数据结构常常从两头地位操作数据的效率是极低的,所以除非必要不倡议这样做。

add(o)

BlockingQueueadd() 办法能够将 o 对象以参数的模式插入到队列外面,如果队列外面有残余空间,将被立刻插入;如果队列外面没有残余空间,add()办法将跑出 IllegalStateException.

offer(o)

BlockingQueueoffer() 办法能够将 o 对象以参数的模式插入到队列外面,如果队列外面有残余空间,将被立刻插入;如果队列外面没有残余空间,offer()办法将返回特定的值false.

offer(o, long millis, TimeUnit timeUnit)

BlockingQueueoffer() 办法有另外一个版本的实现,存在超时工夫的设置参数。这个版本的 offer() 办法将 o 对象以参数的模式插入到队列外面,如果队列外面有残余空间,将被立刻插入;如果队列外面没有残余空间,调用 offer 办法的线程在超时工夫内将被阻塞处于等到状态,当阻塞工夫大于超时工夫之后,队列内如果依然没有残余空间放入新对象,offer()办法将返回false.

put(o)

BlockingQueueput() 办法能够将 o 对象以参数的模式插入到队列外面,如果队列外面有残余空间,将被立刻插入;如果队列外面没有残余空间,调用 put 的办法的线程将被阻塞,直到 BlockingQueue 外面腾出新的空间能够放入对象为止。

take()

BlockingQueuetake() 办法取出并移除队列中的第一个元素(对象),如果 BlockingQueue 队列中不蕴含任何的元素,调用 take() 办法的线程将被阻塞,直到有新的元素对象插入到队列中为止。

poll()

BlockingQueuepoll() 办法取出并移除队列中的第一个元素(对象),如果 BlockingQueue 队列中不蕴含任何的元素,poll()办法将返回null.

poll(long timeMillis, TimeUnit timeUnit)

BlockingQueuepoll(long timeMillis, TimeUnit timeUnit)办法同样存在一个超时工夫限度的版本,失常状况下该办法取出并移除队列中的第一个元素(对象)。如果 BlockingQueue 队列中不蕴含任何的元素,在超时工夫范畴内,如果依然没有新的对象放入队列,这个版本的 poll() 办法将被阻塞处于期待状态;当阻塞工夫大于超时工夫之后,poll(long timeMillis, TimeUnit timeUnit)返回null

remove(Object o)

BlockingQueueremove(Object o) 办法能够从队列中删除一个以参数模式给定的元素对象,remove()办法应用 o.equals(element) 将传入参数 o 与队列中的对象进行一一比对,从而断定要删除的对象是否在队列中存在,如果存在就从队列中删除并返回 true,否则返回 false。

须要留神的是:如果队列中有多个与传入参数 equals 相等的对象,只删除其中一个,不会将队列中所有匹配的对象都删除。

peek()

BlockingQueuepeek() 办法将取出队列中的第一个元素对象,然而并不会将其从队列中删除。如果队列中目前没有任何的元素,也就是空队列,peek()办法将返回null.

element()

BlockingQueueelement()办法将取出队列中的第一个元素对象,然而并不会将其从队列中删除。如果队列中目前没有任何的元素,也就是空队列,element()办法将抛出 NoSuchElementException.

contains(Object o)

BlockingQueuecontains(Object o) 办法用来判断以后队列中是否存在某个对象,该对象与传入参数 o 相等(Objects.equals(o, element)被用来断定对象的相等性)。遍历队列中的所有元素,一旦在队列中发现匹配的元素对象,该办法将返回 true;如果没有任何的元素匹配相等,该办法返回 false。

drainTo(Collection dest)

drainTo(Collection dest)办法一次性的将队列中的所有元素取出到汇合类 Collection dest 对象中保留。

drainTo(Collection dest, int maxElements)

drainTo(Collection dest)办法一次性的从队列中取出 maxElements 个元素到汇合类 Collection dest 对象中保留。

size()

BlockingQueuesize() 办法返回队列中目前共有多少个元素

remainingCapacity()

BlockingQueueremainingCapacity() 办法将返回队列目前还剩多少个可用空间用于放入新的对象。残余空间容量 = 队列的总容量 - 曾经被占用的空间数量

欢送关注我的博客,外面有很多精品合集

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。

  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端拆散 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
  • 《VUE 深入浅出系列》
正文完
 0