1. DelayQueue延时队列操作实例
DelayQueue延时队列,当队列中的元素到达延迟时间时才会被取出。队列元素会按照最终执行时间在队列中进行排序。
最近刚学,本篇先给出一个实际使用的例子。
首先队列对象当然就是DelayQueue。而队列元素则需要实现Delayed这个接口,并实现该接口compareTo方法和getDelay方法。
首先定义该元素及其属性。
class DelayTask implements Delayed { public String name; public Long delayTime; public TimeUnit delayTimeUnit; public Long executeTime;//ms DelayTask(String name, long delayTime, TimeUnit delayTimeUnit) { this.name = name; this.delayTime = delayTime; this.delayTimeUnit = delayTimeUnit; this.executeTime = System.currentTimeMillis() + delayTimeUnit.toMillis(delayTime); } }
getDelay方法的作用即是计算当前时间到执行时间之间还有多长时间。
如下,返回unit单位下该延迟时间的值。
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); }
compareTo方法的作用即是判断队列中元素的顺序谁前谁后。当前元素比队列元素后执行时,返回一个正数,比它先执行时返回一个负数,否则返回0.
@Override
public int compareTo(Delayed o) {
if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) { return 1; }else if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) { return -1; } return 0; }
最后我们用个简单的方法测试下:
public static void main(String[] args) {
DelayQueue<DelayTask> queue = new DelayQueue<>(); queue.add(new DelayTask("1", 1L, TimeUnit.SECONDS)); queue.add(new DelayTask("2", 2L, TimeUnit.SECONDS)); queue.add(new DelayTask("3", 3L, TimeUnit.SECONDS)); System.out.println("queue put done"); while(!queue.isEmpty()) { try { DelayTask task = queue.take(); System.out.println(task.name + ":" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果如下:
queue put done
1:1504498317145
2:1504498318145 3:1504498319145
下面是完整的代码:
public class DelayQueueTest {
public static void main(String[] args) { DelayQueue<DelayTask> queue = new DelayQueue<>(); queue.add(new DelayTask("1", 1000L, TimeUnit.MILLISECONDS)); queue.add(new DelayTask("2", 2000L, TimeUnit.MILLISECONDS)); queue.add(new DelayTask("3", 3000L, TimeUnit.MILLISECONDS)); System.out.println("queue put done"); while(!queue.isEmpty()) { try { DelayTask task = queue.take(); System.out.println(task.name + ":" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } } } class DelayTask implements Delayed { public String name; public Long delayTime; public TimeUnit delayTimeUnit; public Long executeTime;//ms DelayTask(String name, long delayTime, TimeUnit delayTimeUnit) { this.name = name; this.delayTime = delayTime; this.delayTimeUnit = delayTimeUnit; this.executeTime = System.currentTimeMillis() + delayTimeUnit.toMillis(delayTime); } @Override public int compareTo(Delayed o) { if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) { return 1; }else if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) { return -1; } return 0; } @Override public long getDelay(TimeUnit unit) { return unit.convert(executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } }
2. 定时任务轮询数据库
3. redis
public class RedisUtil{
private JedisPool jedisPool;
//生产一个任务
public void addItem(String key,long score,String member){
Jedis redis = jedisPool.getResource();
redis.zadd(key,score,member);
}
//发现超时任务
public void getItem(String key){
Jedis redis= jedisPool.getResource();
Set<Tuple> itemSet = redis.zrangeWithScores(key,0,0);
double score=((Tuple)itemSet.toArray()[0]).getScore();
String element=
((Tuple)itemSet.toArray()[0]).getElement();
double currentTime = CalendarUtils.getCurrentTimeInMillis(0);
if(currentTime>=score){
redis.zrem(key,element);
}
}
}