zoukankan      html  css  js  c++  java
  • 优雅实现订单关闭及定时器的使用

    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);
      }
    }
    }
    }
    

      

     



  • 相关阅读:
    志愿者招募 [NOI2008] [鬼畜网络流]
    莫队入门
    分块入门
    高速公路 [HAOI2012] [线段树]
    游历校园 [COGS 614] [欧拉图]
    网络吞吐量 [CQOI2015] [网络流]
    LeetCode 27. Remove Element
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 21. Merge Two Sorted Lists
    LeetCode 20. Valid Parentheses
  • 原文地址:https://www.cnblogs.com/beyang/p/9243467.html
Copyright © 2011-2022 走看看