`
lanhuidong
  • 浏览: 223798 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA定时器

    博客分类:
  • Java
阅读更多

最近有同事提出在项目中使用JDK自带的定时器,之前的任务调度一直使用的是Quartz,对Timer没有研究过。因此研究了下如何使用Timer。

  1. 每一个Timer会启动一个线程(TimerThread),如下代码将产生5个定时器线程
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            for (int i = 0; i < 5; i++) {
                Timer timer = new Timer();
                timer.schedule(new MyTask(i), 10000);
            }
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
            System.out.println(i);
        }
        
    }
     

     
  2. 每一个Timer可以添加多个TimerTask
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            for (int i = 0; i < 5; i++) {
                timer.schedule(new MyTask(i), 10000);
            }
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
            System.out.println(i);
        }
        
    }
    
     

     
  3. TimerTask会被放入一个有优先级的队列(TimerQueue)中
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            for (int i = 0; i < 5; i++) {
                timer.schedule(new MyTask(i), (10-i)*1000);
            }
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
            System.out.println(i);
        }
        
    }
     
  4. Timer和TimerTask都是可以被取消的
  5. 在同一个TimerQueue中,如果前一个TimerTask没有执行完,那么下一个TimerTask是不会被执行的
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            for (int i = 0; i < 5; i++) {
                timer.schedule(new MyTask(i), (10-i)*1000);
            }
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
    //        try {
    //            Thread.sleep(i * 1000);
    //        } catch (InterruptedException e) {
    //            e.printStackTrace();
    //        }
            System.out.println(i + ":" +new Date());
        }
        
    }
     正常的结果,输出相差1秒
    4:Sun Jan 20 22:55:17 CST 2013
    3:Sun Jan 20 22:55:18 CST 2013
    2:Sun Jan 20 22:55:19 CST 2013
    1:Sun Jan 20 22:55:20 CST 2013
    0:Sun Jan 20 22:55:21 CST 2013
     
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            for (int i = 0; i < 5; i++) {
                timer.schedule(new MyTask(i), (10-i)*1000);
            }
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(i * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i + ":" +new Date());
        }
        
    }
     第一个任务的延迟使之后所有任务都延迟
    4:Sun Jan 20 22:57:08 CST 2013
    3:Sun Jan 20 22:57:11 CST 2013
    2:Sun Jan 20 22:57:13 CST 2013
    1:Sun Jan 20 22:57:14 CST 2013
    0:Sun Jan 20 22:57:14 CST 2013
     
  6. schedule(TimerTask task, Date time):在指定时间执行任务,如果指定的时间比早于当前时间,则马上执行
  7. schedule(TimerTask task, long delay):延迟delay毫秒之后执行任务
  8. scheduleAtFixedRate和schedule的区别
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTestCase {
    
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            System.out.println(new Date());
            timer.schedule(new MyTask(0), 1000, 2000);
            timer.scheduleAtFixedRate(new MyTask(1), 1000, 2000);
        }
    
    }
    
    class MyTask extends TimerTask {
        
        private int i;
        
        public MyTask(int i){
            this.i = i;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i + ":" +new Date());
        }
        
    }
     结果如下,scheduleAtFixedRate无论在什么情况下都已固定频率执行,而schedule则可能延迟
    Sun Jan 20 23:06:49 CST 2013
    0:Sun Jan 20 23:06:53 CST 2013
    1:Sun Jan 20 23:06:56 CST 2013
    1:Sun Jan 20 23:06:59 CST 2013
    0:Sun Jan 20 23:07:02 CST 2013
    1:Sun Jan 20 23:07:05 CST 2013
    1:Sun Jan 20 23:07:08 CST 2013
    1:Sun Jan 20 23:07:11 CST 2013
    1:Sun Jan 20 23:07:14 CST 2013
    0:Sun Jan 20 23:07:17 CST 2013

Timer的缺陷:

  1. Timer是基于绝对时间的,因此任务的执行对系统时间变化很敏感
  2. 如果TimerTask执行时间过长,会破坏其他TimerTask的定时精确性
  3. 如果TimerTask抛出一个未受检查的异常,Timer线程并不捕获,线程将被终止,尚未执行的TimerTask将不会再执行

在Java 5.0或者更高的版本中,可以使用ScheduledThreadPoolExecutor代替Timer。

  • 大小: 12.1 KB
  • 大小: 11.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics