`
punishzhou
  • 浏览: 141246 次
社区版块
存档分类
最新评论

Java 的DelayQueue

阅读更多

今天看了一下HBase的代码,发现在很多地方都用了DelayQueue,网上有很多解析DelayQueue的实例

 

http://www.cnblogs.com/jobs/archive/2007/04/27/730255.html

 

提到了DelayQueue的使用场景:

 

a) 关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之。
b) 缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出。
c) 任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求。

一种笨笨的办法就是,使用一个后台线程,遍历所有对象,挨个检查。这种笨笨的办法简单好用,但是对象数量过多时,可能存在性能问题,检查间隔时间不好设置,间隔时间过大,影响精确度,过小则存在效率问题。而且做不到按超时的时间顺序处理。

这场景,使用DelayQueue最适合了。

DelayQueue是一个BlockingQueue,其特化的参数是Delayed。Delayed扩展了Comparable接口,比较的基准为延时的时间值,Delayed接口的实现类getDelay的返回值应为固定值(final)。DelayQueue内部是使用PriorityQueue实现的。

DelayQueue = BlockingQueue + PriorityQueue + Delayed

DelayQueue的关键元素BlockingQueue、PriorityQueue、Delayed。可以这么说,DelayQueue是一个使用优先队列(PriorityQueue)实现的BlockingQueue,优先队列的比较基准值是时间。

http://guji.is-programmer.com/posts/24751.html详细介绍了delayQueue的用法和原理

Delayed是一个无界的阻塞队列.不允许将NULL放入其中. 它的并发是使用了ReentrantLock和对应的一个condition来完成. 其外,DelayQueue的队列头部放置的是延迟期满了最久的一个元素. 如果元素的getDelay()方法返回0或者小于0的时候才能将其出列. DelayQueue中的元素都是实现了Delayed接口,在JDK中, 而Delayed接口继承了Comparable, 在使用DelayQueue之前就需要自己编写一个Delayed的实现类,

 public long getDelay(TimeUnit unit) {
            long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
            return d;
        }

now()函数的实现:
 private static final long NANO_ORIGIN = System.nanoTime();

    /**
     * Returns nanosecond time offset by origin
     */
    final long now() {
        return System.nanoTime() - NANO_ORIGIN;
    }
public int compareTo(Delayed other) {
            if (other == this) // compare zero ONLY if same object
                return 0;
         
          long d = (getDelay(TimeUnit.NANOSECONDS) -
                      other.getDelay(TimeUnit.NANOSECONDS));
            return (d == 0)? 0 : ((d < 0)? -1 : 1);
        }
有几个重要的方法:

take();取队列首元素,若无,则阻塞直至

poll(timeout);取队列首元素,若超过timeout时间仍没有,返回失败

 

在Hbase中,Lease就是以一个DelayQueue存放的。

 

比如说一个当client scan Table的时候,首先会找到scan的startkey所在的Region,构建RegionScanner,将通过RegionScanner加入一个delayqueue,以及维护一个scannerId到Regionscanner的map。HRegionserver启动的时候会起一个Leases的守护线程,时刻监听delayqueue的元素,当有过期时将其从map中移除,从而达到Leases的作用

分享到:
评论
1 楼 di1984HIT 2014-10-11  
写的很好偶~~~~~

相关推荐

Global site tag (gtag.js) - Google Analytics