zoukankan      html  css  js  c++  java
  • 多线程十 Timer

    定时/计算在java中主要使用的是Timer对象,他的内部依然是采用多线程方式进行处理

    它有四个构造方法

    方法名 作用
    Timer() 空参
    Timer(String name) 指定名字
    Timer(boolean isDaemon) 指定为守护线程
    Timer(String name,boolean isDaman) 指定名字,指定为守护线程

    Timer类的主要作用就是设置计划任务,但是封装任务的类确是TimerTask,TimerTask实现了Runable接口,因此我们要做的也就是重写run方法,定义我们的任务


    • 简单使用
    public class demo01 extends TimerTask {
    @Override
    public void run() {
        System.out.println("计划执行了,  "+new Date());
    }
    
    public static void main(String[] args) {
        System.out.println("当前时间  "+ new Date());
    
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND,5);
        Date time = calendar.getTime();
        demo01 task = new demo01();
        Timer timer = new Timer();
        timer.schedule(task,time);
        System.out.println("主线程结束了...");
    }
    }
    

    程序执行完了,但是进程仍然没有被撤销,呈红色状态,那是因为每创建一个Timer对象,就是启动一条线程,并且这条线程不是守护线程,会一直执行下去


    常用的几个Timer对象的API

    1. 安排在指定的时间执行指定的任务,如果时间过去了,立即执行

    void schedule(TimerTask task,Date time)
    

    一个Timer对象,可以拥有多个TimerTask,而TimerTask是以队列的方法,一个一个顺序执行,这也就可能导致执行的时间和预期的时间不一样,因为前面的任务执行的时间可能比较长,那么后面的任务也就被延后了


    2. 在指定的日期到达之后,按照指定的时间间隔,执行一次某任务

    schedule(TimerTask task , Date firstTime,Long period)
    

    注意点:

    1. firstTime晚于当前时间,计划未来
    2. firstTime早于当前时间,计划立即执行
    3. 任务依然可能被延迟

    3, 以当前时间为准,在此时间基础上延迟指定的时间毫秒数执行一次TimerTask任务

    schedule(TimerTask task, Long delay)
    

    5 .当前的时间为参考,在此时间基础上延迟指定的毫秒数,再以某一个时间间隔,无限次执行某一任务

    schedule(TimerTask task,Long delay,Long period)
    

    6. 测试schedule&scheduleAtFixedRate几种情况

    不延迟 描述
    Date类型 下一次执行任务的时间,都是上一次任务开始的时间+period
    Long类型 第一次任务执行的时间是任务开始的时间+delay,接下来执行任务的时间是上一次任务开始的时间+priod
    延迟 描述
    Date类型 下一次执行任务的时间,都是上一次任务结束的时间+period
    Long类型 下一次执行任务的时间是上一次任务结束的时间+priod

    7. 追赶性

    举个例子什么是追赶性,假如说,程序运行到A行代码时,时间是t1,程序继续往下执行,遇到了B行代码,我们希望,B在A前10秒执行给定的任务,可是按照我们的顺序,A已经执行了,那么实现我们的要求就用到了scheduleAtFixedRate的追赶性
    示例代码:

    /*
    * schedule的追赶性
    * */
    public class demo03 extends TimerTask {
    
    
        @Override
        public void run() {
            System.out.println("任务开始的时间"+new Date());
            System.out.println("任务结束的时间"+new Date());
        }
    
        public static void main(String[] args) {
            System.out.println("现在执行的时间+"+new Date());
    
            demo03 task = new demo03();
    
            Calendar instance = Calendar.getInstance();
               instance.set(Calendar.SECOND,instance.get((Calendar.SECOND)-10));
            Date time = instance.getTime();
            System.out.println("计划执行的时间"+ time);
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(task,time,2000);
        }
    }
    
    

    结果:

    现在执行的时间+Sat Feb 16 07:17:14 CST 2019
    计划执行的时间Sat Feb 16 07:17:07 CST 2019
    任务开始的时间Sat Feb 16 07:17:14 CST 2019
    任务结束的时间Sat Feb 16 07:17:14 CST 2019
    任务开始的时间Sat Feb 16 07:17:14 CST 2019
    任务结束的时间Sat Feb 16 07:17:14 CST 2019
    任务开始的时间Sat Feb 16 07:17:14 CST 2019
    任务结束的时间Sat Feb 16 07:17:14 CST 2019
    任务开始的时间Sat Feb 16 07:17:14 CST 2019
    任务结束的时间Sat Feb 16 07:17:14 CST 2019
    任务开始的时间Sat Feb 16 07:17:15 CST 2019
    任务结束的时间Sat Feb 16 07:17:15 CST 2019
    任务开始的时间Sat Feb 16 07:17:17 CST 2019
    任务结束的时间Sat Feb 16 07:17:17 CST 2019
    任务开始的时间Sat Feb 16 07:17:19 CST 2019
    任务结束的时间Sat Feb 16 07:17:19 CST 2019
    任务开始的时间Sat Feb 16 07:17:21 CST 2019
    任务结束的时间Sat Feb 16 07:17:21 CST 2019
    任务开始的时间Sat Feb 16 07:17:23 CST 2019
    ...
    

    TimerTaskTimer的cancel方法

    • TimerTask的cancel()自然由TimerTask对象调用,它本身是任务队列中的一个任务,作用是把自身从任务队列中进行清除
    • Timer的cancel()方法**把整个任务队列清除

    Timer的cancel的注意事项

    public class demo02 extends TimerTask {
    
        private int i;
    
        public demo02(int i) {
            this.i = i;
        }
    
        @Override
        public void run() {
            System.out.println("任务被第"+i+"次执行,没有被取消");
        }
    
        public static void main(String[] args) {
            int i=0;
            Calendar calendar = Calendar.getInstance();
            Date time = calendar.getTime();
    
            while(true){
                i++;
                Timer timer = new Timer();
                timer.schedule(new demo02(i),time);
                timer.cancel();
            }
    
        }
    

    运行结果

    任务被第32412次执行,没有被取消
    

    原因是Timer类中的cancel方法,有时抢不到任务队列的锁,而让TimerTask类中的任务正常执行


    参考书籍<<java多线程编程核心技术>>高洪岩著

  • 相关阅读:
    POJ 1330:Nearest Common Ancestors【lca】
    图论中一类问题的总结 :必须边(点) 可行边(点)
    POJ 1486 Sorting Slides【二分图匹配】
    POJ 2375 Cow Ski Area【tarjan】
    Unity打开AppStore进行评论
    Unity3D UGUI不规则图片点击事件处理
    Unity3D之聊天框怎么跟随内容大小而变换
    Unity3D之小物体层消隐技术
    Unity3D之新手引导(责任链模式)
    Unity3D之FSM有限状态机
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/11150351.html
Copyright © 2011-2022 走看看