今天第一次接触DelayQueue,源于项目中的话单解析入库的拆分线程中引入,首先简单了解一下DelayQueue:
DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed 元素。
问题1:如何来判断延迟期是否满了呢? ----后面解答,下面继续。
DelayQueue阻塞队列在我们系统开发中也常常会用到,例如:缓存系统的设计,缓存中的对象,超过了空闲时间,需要从缓存中移出;任务调度系统,能够准确的把握任务的执行时间。我们可能需要通过线程处理很多时间上要求很严格的数据,如果使用普通的线程,我们就需要遍历所有的对象,一个一个的检查看数据是否过期等,首先这样在执行上的效率不会太高,其次就是这种设计的风格也大大的影响了数据的精度。一个需要12:00点执行的任务可能12:01才执行,这样对数据要求很高的系统有更大的弊端。由此我们可以使用DelayQueue。
DelayQueue队列中保存的是实现了Delayed接口的实现类,里面必须实现getDelay()和compareTo()方法,前者用于取DelayQueue里面的元素时判断是否到了延时时间,否则不予获取,是则获取。 compareTo()方法用于进行队列内部的排序。
------ 解答了第一个问题。
getDelay(TimeUnit unit){
return unit.convert(time - now(),TimeUnit.NANOSECONDES);//time为设定的间隔时间
}
compareTo(Object object){
if(object instanceof SchuduledTask){
SchuduledTask task = (SchuduledTask) object ;
long l = this.time - task.time;
if(l > 0) return 1 ; //比当前的小则返回1,比当前的大则返回-1,否则为0
else if(l < 0 ) return -1;
else return 0;
}
}
其他关联知识点:
System.currentTimeMillis返回的是从1970.1.1 UTC 零点开始到现在的时间,精确到毫秒,平时我们可以根据System.currentTimeMillis来计算当前日期,星期几等,可以方便的与Date进行转换
System.nanoTime提供相对精确的计时,但是不能用他来计算当前日期返回最准确的可用系统计时器的当前值
java 之DelayQueue实际运用示例 参考:http://www.cnblogs.com/sunzhenchao/p/3515085.html
参考的相关资料,再次说明:
DelayQueue的原理和使用浅谈:http://express.ruanko.com/ruanko-express_69/tech-overnight5.html
DelayQueue队列研究:http://blog.csdn.net/flyingpig4/article/details/6043128
精巧好用的DelayQueue:http://www.cnblogs.com/jobs/archive/2007/04/27/730255.html
System.nanoTime与System.currentTimeMillis的区别:http://blog.csdn.net/dliyuedong/article/details/8806868
System.nanoTime() 的隐患:http://hold-on.iteye.com/blog/1943436
TimeUnit:http://blog.csdn.net/hudashi/article/details/6936604