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() |
下面的办法的四种行为别离的含意是
- 抛出异样: 如果调用办法后不能立刻响应后果(空队列或满队列),则抛出异样。
- 返回特定值: 如果调用办法后不能立刻响应后果(空队列或满队列),则返回特定的值(通常是 true/false),true 示意办法执行胜利,否则示意办法执行失败。
- 阻塞后始终期待: 如果调用办法后不能立刻响应后果(空队列或满队列),该办法将被阻塞始终处于期待状态。
- 阻塞后期待超时: 如果调用办法后不能立刻响应后果(空队列或满队列),该办法将在肯定工夫范畴内被阻塞期待,也就是在超时工夫范畴内阻塞。当超出超时工夫之后,办法线程将不再阻塞,而是返回一个特定的值(通常是 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 深入浅出系列》