原文连接:(http://www.studyshare.cn/blog-front//blog/details/1167/0 )

一、队列及阻塞队列概念

1、队列:是一种特殊线性表,特殊之处在于操作是受限制的,只允许在表的前端进行删除操作,在表的后端进行插入操作。进行删除操作的端为对列头,进

行插入操作的端为队列尾。插入一个元素称之为入队,删除一个元素称为出队,最先插入的元素最先出队,因此队列是一个先进先出的线性表。

2、阻塞队列:所谓阻塞队列,就是阻塞队列中有元素并且队列已经满了的时候,其他线程继续给队列中插入元素会被阻塞,直到队列有空间可存放为止;如

果队列中为空的时候,从队列中获取元素的线程也会被阻塞,直到队列中有元素可获取时为止。

3、生产者消费者模式:如果使用阻塞队列,则必定会使用生产者消费者模式,所谓生产者消费者模式是通过平衡生产线程和消费线程的工作能力来提高程序

整体处理数据的速度。

现在有两个线程,生产者就是一个生产数据的线程,消费者就是一个消费数据的线程,假如生产者线程产生数据很快,消费者线程消费数据很慢,那么生产者

线程就必须等待消费者线程处理完才能继续生产数据,同理,消费者线程需要等生产者线程产生了数据才能继续消费数据。

以上就是生产消费能力不均衡,为解决这个问题,便产生了生产者消费者模式,在生产者消费者之间使用一个容器来解耦合,使得生产者和消费者两者之间不

直接通信,生产者产生的数据往容器中(阻塞队列)尾部加入,消费者从阻塞队列头部去获取需要消费的数据。队列就相当于一个缓冲区,平衡了生产消费两

者的处理能力。

二、DelayQueue延时队列的应用案例

jdk为我们提供了很多阻塞队列的类,在此不一一列举,此处讲讲特别有用,且特别常用的一个阻塞队列--DelayQueue,该类在java.util.concurrent包下,该类

的特殊之处在于,这是一个带有延时功能的阻塞队列。开发中常用的场景如下:

1、缓存系统设计:可以使用DelayQueue保存缓存元素,并给该元素设置有效期,使用一个线程循环查询DelayQueue,如果一旦能从DelayQueue中获取到数

据,则表明该缓存元素到期了。

2、订单到期、限时支付:很多电商系统都有用户下单后限时支付功能,限定30分钟或者24小时需要去支付订单,否则该订单就会失效,需要重新下单。那么使

用DelayQueue解决这种需求是比较优雅的解决方案(不优雅的解决方案就是使用定时器进行定时轮询)。有一篇文章专门详细介绍了限时订单的几种解决方案,

参考限时订单实现方案(DelayQueue,ActivityMQ)

此处以缓存系统设计为例,做简单的代码实现,展现一下DelayQueue的具体使用方式。

(1)、定义一个实现了Dalayed接口的实体类ItemVo,该类用来设置缓存过期时间和缓存数据

2、生产者、消费者线程实现

3、运行效果:

三、DelayQueue源码分析

阻塞队列的实现原理:使用等待通知模式实现,例如当生产者往一个满的队列中插入元素时,会被阻塞,当消费者将队列中的元素消费掉后,会通知生产者当前

队列可用。这就是等待通知模式。接下来看看DelayQueue的源码,了解它是如何实现的。

1、看DelayQueue的take()方法

2、看DelayQueue的put()方法,put中调用的是offer()方法,直接看offer()方法,如下

总结:DelayQueue使用的是PriorityQueue队列+等待通知机制来实现的。以上就是延时阻塞队列DelayQueue的使用及源码分析,如有疏漏之处,欢迎留言讨论。

原创文章,转载请注明出处。

java开发工具下载地址及安装教程大全,点这里
更多深度技术文章,在这里

并发容器之阻塞队列DelayQueue的使用案例及源码分析的更多相关文章

  1. Java并发容器之阻塞队列BlockingQueue

    BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满:从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空. Bloc ...

  2. JUC 并发编程--09, 阻塞队列: DelayQueue, PriorityBlockingQueue ,SynchronousQueue, 定时任务线程池: ScheduledThreadPoolExecutor

    先看DelayQueue 这个是用优先级队列实现的无界限的延迟队列,直接上代码: /** * 这个是 {@link DelayQueue} 延时队列 的验证使用类 */ class MyDelayed ...

  3. 并发编程之 ConcurrentHashMap(JDK 1.8) putVal 源码分析

    前言 我们之前分析了Hash的源码,主要是 put 方法.同时,我们知道,HashMap 在并发的时候是不安全的,为什么呢?因为当多个线程对 Map 进行扩容会导致链表成环.不单单是这个问题,当多个线 ...

  4. Java并发编程:阻塞队列(转载)

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  5. 【转】Java并发编程:阻塞队列

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

  6. Java并发编程:阻塞队列 <转>

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

  7. 12、Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  8. (转)Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  9. Java多线程高并发学习笔记——阻塞队列

    在探讨可重入锁之后,接下来学习阻塞队列,这边篇文章也是断断续续的写了很久,因为最近开始学ssm框架,准备做一个自己的小网站,后续可能更新自己写网站的技术分享. 请尊重作者劳动成果,转载请标明原文链接: ...

随机推荐

  1. 右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐)

    (1)右键计算机->属性->高级系统设置->高级->环境变量,添加环境变量(推荐) QTDIR:D:\Software\Qt\Qt5.2.0\5.2.0\msvc2010_op ...

  2. C++安全异常std:auto_ptr

    auto_ptr它是C++标准库(<utility>)为了一个智能指针类模板来解决资源泄漏所提供的问题(注意:这只是一个简单的智能指针) auto_ptr在事实原则的实现RAII,对资源的 ...

  3. ShopNC本地生活o2o网站的源代码,没有域名限制

    较前某VIP源代码论坛分享了套ShopNC本地生活o2o站点系统.下载过来却发现根本不能用,所以一直没分享出来.今天咱们这边分享的这套ShopNC本地生活o2o站点源代码,无不论什么的限制,直接ins ...

  4. 怎样从一名程序员过度到项目经理(整理自csdn论坛) 选择自 whoopee 的 Blog

    1.从程序员到PM,是一条脱变的路,事实上程序员走的路最终不应该是项目经理.首先有一点需要明白的就是,一定规模的项目中,项目经理不需要太懂技术,他可以是一知半解.项目经理的任务不是在技术方面,技术相关 ...

  5. react项目实践——(4)依赖安装与配置

    1. 修改package.json,添加需要安装的包 { "name": "myapp", "version": "1.0.0&q ...

  6. Python第一个基本教程4章 词典: 当指数不工作时也

    Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "copyri ...

  7. WPF 跨界面调用程序

    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (System.Threading.ThreadStart)delegate() { sE ...

  8. 读BeautifulSoup官方文档之html树的搜索(2)

    除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的 ...

  9. Springboot统一配置Jackson

    经常要为接口响应对象设置属性,序列化的时候是不是包含空值,反序列化的时候是否忽略不认识的字段.所以,必须要手动制定ObjectMapper或者在类上声明 @JsonInclude(Include.NO ...

  10. wcf 代理实例

    通过过代理调用 wcf服务 using Microsoft.Extensions.Options; using System; using System.Collections.Generic; us ...