优雅实现订单关闭及定时器的使用

Java定时器(一)Timer和TimerTask

 

方式一:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date date)  

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("………这里是逻辑代码………");
}
}, 5000,5000);
while(true){
Thread.sleep(1000);
System.out.println(new Date().getSeconds());
}
}

  

 

此代码的结果是5秒后输出"……这里是逻辑代码……"

方式二:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行 schedule(TimerTask task,long delay,long period)

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("……这里是逻辑代码……");
}
},new Date(), 5000);
while(true){
Thread.sleep(1000);
System.out.println(new Date().getSeconds());
}
}

  

 

此段代码输出结果为延迟5秒后,每隔5秒输出"……这里是逻辑代码……"

方式三:设定指定任务task在指定开始时间firstTime开始后进行固定频率peroid的执行 schedule(TimerTask task,Date firstTime,long period)

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("……这里是逻辑代码……");
}
},new Date(), 5000);
while(true){
Thread.sleep(1000);
System.out.println(new Date().getSeconds());
}
}

  

 

这里的代码输出结果为在当前时间开始后马上输出"……这里是逻辑代码……",之后每隔5秒输出"……这里是逻辑代码……"

 

 

 

 

 

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();
  while(true){
  Set<Tuple> itemSet = redis.zrangeWithScores(key,0,0);
  if(itemSet==null){Thread.sleep(1000); continue;}
  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);
  }
}
}
}

  

 



posted @ 2018-06-29 14:56  彼扬  阅读(784)  评论(0编辑  收藏  举报

感谢您的阅读,如果有了您的奉献系统会更加完善