• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > java利用delayedQueue实现本地的延迟队列

java利用delayedQueue实现本地的延迟队列

作者:jsondream 字体:[增加 减小] 来源:互联网 时间:2017-05-28

jsondream 通过本文主要向大家介绍了java队列实现,用java实现阻塞队列,java实现消息队列,java用数组实现队列,java实现阻塞队列等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一、了解DelayQueue

DelayQueue是什么?

DelayQueue是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。

注意:不能将null元素放置到这种队列中。

DelayQueue能做什么?

在我们的业务中通常会有一些需求是这样的:

  • 淘宝订单业务:下单之后如果三十分钟之内没有付款就自动取消订单。
  • 饿了吗订餐通知:下单成功后60s之后给用户发送短信通知。

那么这类业务我们可以总结出一个特点:需要延迟工作。
由此的情况,就是我们的DelayQueue应用需求的产生。

二、怎么用DelayQueue来解决这类的问题

先声明一个Delayed的对象

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * <p>
 * [任务调度系统]
 * <br>
 * [队列中要执行的任务]
 * </p>
 *
 * @author wangguangdong
 * @version 1.0
 * @Date 2015年11月22日19:46:39
 */
public class Task<T extends Runnable> implements Delayed {
 /**
  * 到期时间
  */
 private final long time;

 /**
  * 问题对象
  */
 private final T task;
 private static final AtomicLong atomic = new AtomicLong(0);

 private final long n;

 public Task(long timeout, T t) {
  this.time = System.nanoTime() + timeout;
  this.task = t;
  this.n = atomic.getAndIncrement();
 }

 /**
  * 返回与此对象相关的剩余延迟时间,以给定的时间单位表示
  */
 @Override
 public long getDelay(TimeUnit unit) {
  return unit.convert(this.time - System.nanoTime(), TimeUnit.NANOSECONDS);
 }

 @Override
 public int compareTo(Delayed other) {
  // TODO Auto-generated method stub
  if (other == this) // compare zero ONLY if same object
   return 0;
  if (other instanceof Task) {
   Task x = (Task) other;
   long diff = time - x.time;
   if (diff < 0)
    return -1;
   else if (diff > 0)
    return 1;
   else if (n < x.n)
    return -1;
   else
    return 1;
  }
  long d = (getDelay(TimeUnit.NANOSECONDS) - other.getDelay(TimeUnit.NANOSECONDS));
  return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
 }

 public T getTask() {
  return this.task;
 }

 @Override
 public int hashCode() {
  return task.hashCode();
 }

 @Override
 public boolean equals(Object object) {
  if (object instanceof Task) {
   return object.hashCode() == hashCode() ? true : false;
  }
  return false;
 }


}
</div>

再实现一个管理延迟任务的类

import org.apache.log4j.Logger;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * [任务调度系统]
 * <br>
 * [后台守护线程不断的执行检测工作]
 * </p>
 *
 * @author wangguangdong
 * @version 1.0
 * @Date 2015年11月23日14:19:40
 */
public class TaskQueueDaemonThread {

 private static final Logger LOG = Logger.getLogger(TaskQueueDaemonThread.class);

 private TaskQueueDaemonThread() {
 }

 private static class LazyHolder {
  private static TaskQueueDaemonThread taskQueueDaemonThread = new TaskQueueDaemonThread();
 }

 public static TaskQueueDaemonThread getInstance() {
  return LazyHolder.taskQueueDaemonThread;
 }

 Executor executor = Executors.newFixedThreadPool(20);
 /**
  * 守护线程
  */
 private Thread daemonThread;

 /**
  * 初始化守护线程
  */
 public void init() {
  daemonThread = new Thread(() -> execute());
  daemonThread.setDaemon(true);
  daemonThread.setName("Task Queue Daemon Thread");
  daemonThread.start();
 }

 private void execute() {
  System.out.println("start:" + System.currentTimeMillis());
  while (true) {
   try {
    //从延迟队列中取值,如果没有对象过期则队列一直等待,
    Task t1 = t.take();
    if (t1 != null) {
     //修改问题的状态
     Runnable task = t1.getTask();
     if (task == null) {
      continue;
     }
     executor.execute(task);
     LOG.info("[at task:" + task + "] [Time:" + System.currentTimeMillis() + "]");
    }
   } catch (Exception e) {
    e.printStackTrace();
    break;
   }
  }
 }

 /**
  * 创建一个最初为空的新 DelayQueue
  */
 private DelayQueue<Task> t = new DelayQueue<>();

 /**
  * 添加任务,
  * time 延迟时间
  * task 任务
  * 用户为问题设置延迟时间
  */
 public void put(long time, Runnable task) {
  //转换成ns
  long nanoTime = TimeUnit.NANOSECONDS.convert(time, TimeUnit.MILLISECONDS);
  //创建一个任务
  Task k = new Task(nanoTime, task);
  //将任务放在延迟的队列中
  t.put(k);
 }

 /**
  * 结束订单
  * @param task
  */
 public boolean endTask(Task<Runnable> task){
  return t.remove(task);
 }
}
</div>

使用方法

  • 在容器初始化的时候调用init方法.
  • 实现一个runnable接口的类,调用TaskQueueDaemonThread的put方法传入进去.
  • 如果需要实现动态的取消任务的话,需要task任务的类重新hashcode方法,最好用业务限制hashcode的冲突发生.

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • java利用delayedQueue实现本地的延迟队列
  • java利用delayedQueue实现本地的延迟队列

相关文章

  • 2017-05-28Spring Boot 集成Dubbo框架实例
  • 2017-05-28利用spring aop实现动态代理
  • 2017-05-28关于Socket的解析以及双方即时通讯的java实现方法
  • 2017-05-28Java IO中字节流复制图片实现代码
  • 2017-05-28Java IO中字节流复制图片实现代码
  • 2017-05-28Spring boot实现热部署的两种方式详解
  • 2017-05-28SpringMVC4+MyBatis+SQL Server2014实现数据库读写分离
  • 2017-05-28Java this()和super()的使用注意
  • 2017-05-28详解使用Spring Boot开发Web项目
  • 2017-05-28Mybatis返回插入主键id的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Hibernate对数据库删除、查找、更新操作实例代码
    • Java IO流 文件的编码实例代码
    • JAVA简单实现MD5注册登录加密实例代码
    • 详解Spring框架---IOC装配Bean
    • Spring AOP 自定义注解的实现代码
    • javaweb中mysql数据库连接步骤方法及其实例
    • java基于dom4j包实现对XML解析的方法
    • Java 操作Properties配置文件详解
    • BufferedInputStream(缓冲输入流)详解_动力节点Java学院整理
    • struts2实现文件上传显示进度条效果

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有