Java~util包中Timer的使用, 演示cancel方法 和 对比schedule和scheduleAtFixedRate方法

   日期:2020-10-13     浏览:94    评论:0    
核心提示:文章目录Timer常见问题方法schedule(Timer Task task, long delay)方法schedule(Timer Task task, long delay, long period)cancel方法TimerTask类的cancel()方法Timer类的cancel()方法timer.cancel的最常见一个问题对比schedule和scheduleAtFixedRate方法TimerTimer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类执行计划任务

文章目录

    • Timer
      • 常见问题
      • 方法schedule(Timer Task task, long delay)
      • 方法schedule(Timer Task task, long delay, long period)
    • cancel方法
      • TimerTask类的cancel()方法
      • Timer类的cancel()方法
        • timer.cancel的最常见一个问题
    • 对比schedule和scheduleAtFixedRate方法

Timer

  • Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类
  • 执行计划任务的代码要放人TimerTask的子类中,因为TimerTask是一个抽象类。而且要重写其run方法 因为这是一个抽象方法.

常见问题

  1. 任务执行完了, 但进程并没有销毁,
  • 通过源码查看构造方法可以得知,创建一个 Timer就是启动一个新的线程,这个新启动的线程并不是守护线程,它一直在运行。
  • 如果想要将其变为守护线程就在初始化timer的时候传入一个true
public class Demo1 { 

    public static void main(String[] args) throws InterruptedException { 
        Timer timer = new Timer(true);
        Task task = new Task();
        timer.schedule(task, 1000);
        
        Thread.sleep(1000);
    }
}

class Task extends TimerTask { 

    @Override
    public void run() { 
        System.out.println("Listen");
    }
}
  1. 如果我们定的执行任务的时间在未来, 这种会在将来正常执行, 如果我们定的任务在过去, 那么这个任务就立刻执行.
  2. TimerTask是以队列的方式一个一个被顺序执行的,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也会被延迟。

方法schedule(Timer Task task, long delay)

  • 该方法的作用是以执行schedule(TimerTasktask,long delay)方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数delay后执行一次TimerTask任务。
  • 演示
public class Demo2 { 

    public static void main(String[] args) { 
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() { 
            @Override
            public void run() { 
                System.out.println("执行时间: " + new Date().toString());
                System.out.println("l love listen");
            }
        };
        System.out.println("此时: " + new Date().toString());
        timer.schedule(timerTask, 1000);
    }
}

方法schedule(Timer Task task, long delay, long period)

  • 该方法的作用是以执行schedule ( TimerTask task, long delay, long period)方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数delay,再以某一间隔period时间无限次数地执行某一任务。
  • 演示
public class Demo3 { 

    public static void main(String[] args) { 
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() { 
            @Override
            public void run() { 
                System.out.println("执行时间" + new Date().toString());
                System.out.println("l love listen");
            }
        };
        timer.schedule(timerTask, 1000, 1000);
    }
}

  • 凡是使用方法中带有period参数的,都是无限循环执行TimerTask中的任务。

cancel方法

TimerTask类的cancel()方法

  • TimerTask类中的cancel方法的作用是将自身从任务队列中清除。
public class Demo4 { 

    public static void main(String[] args) { 
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() { 

            volatile int count = 0;

            @Override
            public void run() { 
                System.out.println("执行时间" + new Date().toString());
                System.out.println("l love listen");
                count++;
                if (count == 3) { 
                    System.out.println("执行cancel");
                    this.cancel();
                }
            }
        };
        timer.schedule(timerTask, 1000, 1000);
    }
}

  • TimerTask类的cancel()方法是将自身从任务队列中被移除,其他任务不受影响。

Timer类的cancel()方法

  • 和TimerTask类中的cancel() 方法清除自身不同,Timer 类中的cancel()方法的作用是将任务队列中的全部任务清空。
public class Demo5 { 

    public static void main(String[] args) { 
        Timer timer = new Timer();
        //创建俩个task
        TimerTask timerTask = new TimerTask() { 
            volatile int count = 0;
            @Override
            public void run() { 
                System.out.println("A 执行时间" + new Date().getTime());
                System.out.println("l love listen");
                count++;
                if (count == 3) { 
                    System.out.println("执行timer.cancel");
                    timer.cancel();
                }
            }
        };
        TimerTask timerTask1 = new TimerTask() { 
            @Override
            public void run() { 
                System.out.println("B 执行时间" + new Date().getTime());
                System.out.println("l love swy");
            }
        };
        timer.schedule(timerTask, 1000, 1000);
        timer.schedule(timerTask1, 500, 500);
    }
}

  • 全部任务都被清除,并且进程被销毁,按钮由红色变成灰色。

timer.cancel的最常见一个问题

  • Timer类中的cancel()如果执行了, 表示这个定时器就用不成了, 所以即使你再往定时器里加任务, 也是不能执行的
public class Demo6 { 

    public static void main(String[] args) { 
        Timer timer = new Timer();
        //创建俩个task
        TimerTask timerTask = new TimerTask() { 
            @Override
            public void run() { 
                System.out.println("A 执行时间" + new Date().getTime());
                System.out.println("l love listen");
            }
        };
        TimerTask timerTask1 = new TimerTask() { 
            @Override
            public void run() { 
                System.out.println("B 执行时间" + new Date().getTime());
                System.out.println("l love swy");
            }
        };
        while (true) { 
            timer.schedule(timerTask, 1000, 1000);
            timer.schedule(timerTask1, 500, 500);
            timer.cancel();
        }
    }
}

对比schedule和scheduleAtFixedRate方法

  • 方法schedule和方法scheduleAtFixedRate都会按顺序执行,所以不要考虑非线程安全的情况。方法schedule和scheduleAtFixedRate主要的区别只在于不延时的情况使用schedule方法:如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的“开始"时的时间来计算。
    使用scheduleAtFixedRate方法:如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的“结束”时的时间来计算。
  • 延时的情况则没有区别,也就是使用schedule或scheduleAtFixedRate方法都是如果执行任务的时间被延时,那么下一次任务的执行时间参考的是上一次任务“结束”时的时间来计算。
  • schedule方法不具有追赶性, 而scheduleAtFixedRate具有追赶性, 追赶性就是如果我们定的是循环执行的任务, 且定的任务在将来, 那么使用schedule不会弥补时间上的空缺, 而使用scheduleAtFixedRate会补充执行, 把欠下的都执行回来.
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服