zoukankan      html  css  js  c++  java
  • Timer 的缺陷

      java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。但是,Timer存在一些缺陷,因此你应该考虑使用ScheduledThreadPoolExecutor作为代替品,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。

        Timer的另一个问题在于,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。

    public class OutOfTime {
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            timer.schedule(new ThrowTask(), 1);
            SECONDS.sleep(1);
            timer.schedule(new ThrowTask(), 1);
            SECONDS.sleep(5);
        }
    
        static class ThrowTask extends TimerTask {
            public void run() {
                /*try {
                     Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }*/
                throw new RuntimeException();
            }
        }
    }

    执行结果

    Exception in thread "Timer-0" java.lang.RuntimeException
        at net.jcip.examples.OutOfTime$ThrowTask.run(OutOfTime.java:31)
        at java.util.TimerThread.mainLoop(Timer.java:555)
        at java.util.TimerThread.run(Timer.java:505)
    Exception in thread "main" java.lang.IllegalStateException: Timer already cancelled.
        at java.util.Timer.sched(Timer.java:397)
        at java.util.Timer.schedule(Timer.java:193)
        at net.jcip.examples.OutOfTime.main(OutOfTime.java:19)

    Timer单线程执行任务,任务有可能丢失或执行时间不准确。

      Timer执行任务时只是创建了单个线程。如果一个时间任务执行的时间比较长,那么其他任务执行时间的准确性就会受影响。比如每隔1秒执行一次任务,中间有个长任务执行时间超过5秒,那么在上一个任务执行完成时,会快速执行4次或者丢失任务。

    public class OutOfTime {
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            timer.schedule(new ThrowTask(), 1);
            SECONDS.sleep(1);
            timer.schedule(new ThrowTask(), 1);
            SECONDS.sleep(5);
        }
    
        static class ThrowTask extends TimerTask {
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                throw new RuntimeException();
            }
        }
    }

    执行结果

    Exception in thread "Timer-0" java.lang.RuntimeException
        at net.jcip.examples.OutOfTime$ThrowTask.run(OutOfTime.java:31)
        at java.util.TimerThread.mainLoop(Timer.java:555)
        at java.util.TimerThread.run(Timer.java:505)
  • 相关阅读:
    扩展LVM 逻辑卷存储空间
    Linux Shell远程执行命令(命令行与脚本方式)
    vsftpd FTP服务器配置
    初识小米Minos
    使用Libpng库实现Tiny6410显示PNG图片
    uCos-II内存管理
    应用程序调用tslib出现segmentation fault
    Linux-2.6.39在Tiny6410上的移植
    Linux-2.6.39在Tiny6410上的移植
    Tiny6410移植tslib
  • 原文地址:https://www.cnblogs.com/mjorcen/p/4235409.html
Copyright © 2011-2022 走看看