在实践中使用延迟队列

通常,在某些情况下,当您有某种工作或作业队列时,有必要不立即处理每个工作项或作业,而是要延迟一些时间。 例如,如果用户单击一个按钮来触发要完成的某项工作,而一秒钟后,用户意识到他/她错了,则该工作根本就不会开始。 或者,如果有一个用例,则在经过一些延迟(过期)后应删除队列中的某些工作元素。

有很多实现,但是我想描述的是使用纯JDK并发框架类: DelayedQueue和Delayed接口。

让我从定义工作项的简单(且为空)界面开始。 我跳过诸如属性和方法之类的实现细节,因为它们并不重要。

package com.example.delayed;public interface WorkItem {// Some properties and methods here
}

我们模型中的下一个类将代表被推迟的工作项并实现Delayed接口。 仅有几个基本概念需要考虑:延迟本身和相应工作项已提交的实际时间。 这就是到期日的计算方式。 因此,我们通过引入PostponedWorkItem类来做到这一点。

package com.example.delayed;import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class PostponedWorkItem implements Delayed {private final long origin;private final long delay;private final WorkItem workItem;public PostponedWorkItem( final WorkItem workItem, final long delay ) {this.origin = System.currentTimeMillis();this.workItem = workItem;this.delay = delay;}@Overridepublic long getDelay( TimeUnit unit ) {return unit.convert( delay - ( System.currentTimeMillis() - origin ), TimeUnit.MILLISECONDS );}@Overridepublic int compareTo( Delayed delayed ) {if( delayed == this ) {return 0;}if( delayed instanceof PostponedWorkItem ) {long diff = delay - ( ( PostponedWorkItem )delayed ).delay;return ( ( diff == 0 ) ? 0 : ( ( diff < 0 ) ? -1 : 1 ) );}long d = ( getDelay( TimeUnit.MILLISECONDS ) - delayed.getDelay( TimeUnit.MILLISECONDS ) );return ( ( d == 0 ) ? 0 : ( ( d < 0 ) ? -1 : 1 ) );}
}

如您所见,我们创建该类的新实例,并将当前系统时间保存在内部origin属性中。 getDelayed方法计算工作项过期之前剩余的实际时间。 延迟是外部设置,它是构造函数参数。 由于Delayed扩展了此接口,因此必须强制实施Comparable <Delayed> 。

现在,我们大部分完成了! 为了完成该示例,让我们通过实现equalshashCode来确保不会将相同的工作项两次提交到工作队列中(实现非常简单,不需要任何注释)。

public class PostponedWorkItem implements Delayed {...@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ( ( workItem == null ) ? 0 : workItem.hashCode() );return result;}@Overridepublic boolean equals( Object obj ) {if( this == obj ) {return true;}if( obj == null ) {return false;}if( !( obj instanceof PostponedWorkItem ) ) {return false;}final PostponedWorkItem other = ( PostponedWorkItem )obj;if( workItem == null ) {if( other.workItem != null ) {return false;}} else if( !workItem.equals( other.workItem ) ) {return false;}return true;}
}

最后一步是引入某种管理器,该管理器将安排工作项并定期轮询过期的项:见WorkItemScheduler类。

package com.example.delayed;import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;public class WorkItemScheduler {private final long delay = 2000; // 2 secondsprivate final BlockingQueue< PostponedWorkItem > delayed =new DelayQueue< PostponedWorkItem >(); public void addWorkItem( final WorkItem workItem ) {final PostponedWorkItem postponed = new PostponedWorkItem( workItem, delay );if( !delayed.contains( postponed )) {delayed.offer( postponed );}}public void process() {final Collection< PostponedWorkItem > expired = new ArrayList< PostponedWorkItem >();delayed.drainTo( expired );for( final PostponedWorkItem postponed: expired ) {// Do some real work here with postponed.getWorkItem()}}
}

使用BlockingQueue可以确保线程安全和高级别的并发性。 该处理方法应定期运行,以排干工作项队列。 它可以通过Spring Framework中的@ Scheduled注释或JEE 6中的 EJB的@Schedule注释进行注释。

请享用!

参考:在Andriy Redko {devmind}博客上,我们的JCG合作伙伴 Andriy Redko 在实践中使用了延迟队列 。


翻译自: https://www.javacodegeeks.com/2012/04/using-delayed-queues-in-practice.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCL学习八叉树

建立空间索引在点云数据处理中有着广泛的应用&#xff0c;常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构&#xff0c;比较有代表性的包括BSP树&#xff0c;KD树&#xff0c;KDB树&#xff0c;R树&#xff0c;四叉树&#xff0c;八叉树等索引结构&#xff0c;而…

Android实现自定义带文字和图片的Button

在Android开发中经常会需要用到带文字和图片的button&#xff0c;下面来讲解一下常用的实现办法。 一.用系统自带的Button实现 最简单的一种办法就是利用系统自带的Button来实现&#xff0c;这种方式代码量最小。在Button的属性中有一个是drawableLeft&#xff0c;这个 属性可以…

mysql语句中的注释方法_MySQL语句注释方式简介

MySQL支持三种注释方式&#xff1a;1.从‘#字符从行尾。2.从‘-- 序列到行尾。请注意‘-- (双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符等等)。3.从/*序列到后面的*/序列。结束序列不一定在同一行中&#xff0c;因此该语法允许注释跨越多行。…

aqlserver实用程序_sqlserver命令提示实用工具的介绍

除上述的图形化管理工具外&#xff0c;SQL Server2008还提供了大量的命令行实用工具&#xff0c;包括bcp、dtexec、dtutil、osql、reconfig、sqlcmd、sqlwb和tablediff等&#xff0c;下面进行简要说明。dtexec实用工具用于配置和执行SQL Server2008 Intgration Services包。用户…

使用Java和Scala将Play Framework 2应用程序部署到Openshift

几个星期&#xff0c; 马克阿特伍德 &#xff08; Mark Atwood&#xff09; &#xff0c; 豪尔赫阿里斯 &#xff08; Jorge Aliss &#xff09;和我塞巴斯蒂安 斯卡塔诺 &#xff08; SebastinScarano&#xff09;参加了红帽网络研讨会LETS PLAY&#xff01; 在云端&#xff1…

LintCode 387: Smallest Difference

LintCode 387: Smallest Difference 题目描述 给定两个整数数组&#xff08;第一个是数组A&#xff0c;第二个是数组B&#xff09;&#xff0c;在数组A中取A[i]&#xff0c;数组B中取B[j]&#xff0c;A[i]和B[j]两者的差越小越好(|A[i] - B[j]|)。返回最小差。 样例 给定数组A …

android框架----下沉文字Titanic的使用

Titanic is a simple illusion obtained by applying an animated translation on the TextView TextPaint Shaders matrix. Titanic的使用 Titanic的使用&#xff0c;项目结构如下&#xff1a; 一、下载Titanic并且部署到项目中 Titanic的项目地址&#xff1a; https://github…

linux 自动安装mysql_Linux安装mysql

一、下载这里我创建了一目录software用于存放我们待会要下载的mysql包&#xff0c;先去到该目录命令&#xff1a;cd /software命令&#xff1a;wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar下载完成后&#xff0c;你会在software这个…

Quartz Scheduler插件–隐藏的宝藏

尽管在官方文档中进行了简要描述&#xff0c;但我相信Quartz插件了解得还不够多&#xff0c;看看它们有多有用。 本质上&#xff0c;Quartz中的插件是方便的类&#xff0c;用于包装基础侦听器的注册。 您可以自由编写自己的插件&#xff0c;但我们将专注于Quartz随附的现有插件…

mysql查询表名匹配只有字母的_MySQL按某些匹配字母查询表

MySQL查询是MySQL的核心功能&#xff0c;有时候我们需要查找带有某些匹配字母的表。下文对该MySQL查询方式作了详细的介绍&#xff0c;供您参考。在MySQL中我们可以使用LIKE或者NOT LIKE操作符进行比较。在MySQL中模式默认是不区分大小写的。查询示例&#xff0c;student表----…

hdu 1181(Floyed)

变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 20748 Accepted Submission(s): 7494 Problem Description呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的…

读书笔记-你不知道的JS上-混入与原型

继承 mixin混合继承 function mixin(obj1, obj2) {for (var key in obj2) {//重复不复制if (!(key in obj1)) {obj1[key] obj2[key];}}return obj1;} 这种复制是浅复制&#xff0c;对象或者数组函数等都是同一个引用&#xff0c;改变obj1的会同时影响obj2。 寄生继承 ... 隐式…

JUnit和Hamcrest:在assertEquals上进行改进

在我的博客文章中&#xff0c;Java越来越接受静态导入吗&#xff1f; &#xff0c;我讨论了在Java中越来越多地使用静态导入来使代码在某些情况下更流畅。 Java 单元测试特别受静态导入的影响&#xff0c;在此博客文章中&#xff0c;我提供了一个简单的示例&#xff0c;说明如何…

mysql delete temporary denied_这些错误是什么意思?djang中的mysql

我试着运行一个程序&#xff0c;我被给予了一个例子&#xff0c;它就像一个购物网站&#xff0c;使用MySQL数据库而不是Django提供的原始数据库&#xff01;我只是想看看有没有人理解这些错误的含义&#xff1f;任何信息都将不胜感激&#xff01;我本可以提供网页的代码&#x…

C语言 · 芯片测试

基础练习 芯片测试 时间限制&#xff1a;1.0s 内存限制&#xff1a;512.0MB问题描述有n&#xff08;2≤n≤20&#xff09;块芯片&#xff0c;有好有坏&#xff0c;已知好芯片比坏芯片多。每个芯片都能用来测试其他芯片。用好芯片测试其他芯片时&#xff0c;能正确给出被测试…

Animation用法

测试代码及说明&#xff1a; <!DOCTYPE html> <html lang"en-US"> <head><meta charset"UTF-8"><title>Simple CSS3 Animation</title><style type"text/css">#demo {position: absolute;left: 30%;t…

mysql dese_MySQL 5.6-类似于DENSE_RANK的功能,无需订购

小编典典对于 MySQL版本<8.0(OP的版本是5.6)&#xff1a;问题陈述看起来需要DENSE_RANK功能groupVarian; 但是事实并非如此。正如 GordonLinoff解释的那样 &#xff1a;您似乎希望按它们在数据中出现的顺序来枚举它们。假设您的表名是t(请为您的代码相应地更改表名和字段名)…

Spring和JSF集成:动态导航

通常&#xff0c;您的JSF应用程序将需要超越基本的静态导航并开始做出动态导航决策。 例如&#xff0c;您可能想根据用户的年龄重定向他们。 大多数JSF教程建议通过将命令的action属性绑定到支持bean来实现动态导航&#xff1a; <h:commandButton action"#{bean.action…

通过富文本改变UITextFieldPlaceholder颜色

1、通过属性 a、 //文字属性(一般) NSMutableDictionary *attrs [NSMutableDictionary dictionary]; attrs[NSForegroundColorAttributeName] [UIColor blueColor]; NSAttributedString *placeholderStr [[NSAttributedString alloc] initWithString:"手机号" a…

阻塞/非阻塞/同步/异步方法和多线程的关系?没有任何关系,俩不挨着

1.阻塞非阻塞异步同步是针对方法说的&#xff0c;是评判一个方法运行状态的。和多线程完全两个级别。 2.阻塞非阻塞异步同步是针对方法说的&#xff0c;是评判一个方法运行状态的。和多线程完全两个级别。 3.阻塞非阻塞异步同步是针对方法说的&#xff0c;是评判一个方法运行状…