精华内容
下载资源
问答
  • Android 定时器Timer
    千次阅读
    2019-07-29 11:00:29

    定义一个定时器及定义一个TimerTask处理handler事件

    Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
             public void run() {
                                    Thread thread = new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                            Message message = new Message();
                                            message.what = 2;
                                            mHandler.sendMessage(message);
                                        }
                                    });
                                    thread.start();
                                }
        };     
    

    ##开启一个定时器

     timer.schedule(task,200,10000);
    

    说明:
    第一个参数是定时器要做的任务(task),这里是处理handler 消息
    第二参数是什么事件做这个任务(task),这里写的是200ms,即200ms后timer开始处理任务。
    第三个参数是执行任务的时间间隔,即每隔10s执行一次任务(task),如果不写的话,定时器只执行一次任务。

    定时器的请求周期

    定时器如果不销毁的话会一直执行,但定时器一直执行的话,那么程序很可能就会崩溃所以说定时器用完要及时的关闭
    定时器的开启一般会写在onStart里面
    定时器的销毁会写在onStop里面

    销毁定时器

    timer.cancel();
    

    离开本界面的时候就执行这句话那么定时器就不会在执行了,进入本界面时在onStart中执行定时器那么就开启了定时器。
    注意: timer的开启和销毁不一定定义在onStart()或onDestroy()方法中。

    一个定时器代码

     touchtimer = new Timer();
                            touchtimer.schedule(new TimerTask() {
                                @Override
                                public void run() {
                                    Thread thread = new Thread(new Runnable() { //定义一个线程
                                        @Override
                                        public void run() {
                                            Message message = new Message();//定义一个消息message
                                            message.what = 2;                 //自定义一个消息的what属性(区分不同消息)
                                            mHandler.sendMessage(message); //发送消息
                                        }
                                    });
                                    thread.start();                  //开启线程
                                }
                            },300,200);
     public Handler mHandler = new Handler() {       //定义一个Handler并来处理消息
            public void handleMessage(Message msg) { //接受并处理线程发送来的消息
                switch (msg.what) {                 //识别线程发送的消息的what
                    case 2:                         //根据what执行不同的事件方法,这里只定义里一个what
                       执行定义的事件或事件处理方法;   
                        break;
                    default:
                        break;
                }
                super.handleMessage(msg);
            };
            protected void onDestroy() {                 //销毁timer
                super.onDestroy();
                timer.cancel();
               } 
    
    更多相关内容
  • 定时器Timer应用场景非常广泛,在Linux下,有以下几种方法: 1,使用sleep()和usleep() 其中sleep精度是1秒,usleep精度是1微妙,具体代码就不写了。使用这种方法缺点比较明显,在Linux系统中,sleep类函数不能保证...
  • 定时器Timer

    万次阅读 2020-10-20 11:11:29
    定时器Timer 为什么要使用定时器呢? 比如说一个web应用,如果这个应用规模很大,那它的日志数据是不是很多。如果一直存下来服务器的存储量怕是不行吧,需要隔一段时间删除,那么就需要一个线程每隔一段时间去...

    #定时器Timer

    为什么要使用定时器呢?

    比如说一个web应用,如果这个应用规模很大,那它的日志数据是不是很多。如果一直存下来服务器的存储量怕是不行吧,需要隔一段时间删除,那么就需要一个线程每隔一段时间去删除日志数据。

    直接来个程序:

    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TestTimer {
    public static void main(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("我执行了"+"  "+System.currentTimeMillis());
            }
        },1000,2000);
    }
    }
    

    运行结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ym8DcEmP-1603163485909)(https://i.imgur.com/f5551y1.png)]

    Timer 是调度器,TimerTask 调度任务。


    ##Timer类

    ###构造方法

    Timer() 创建一个新的计时器。

    Timer(boolean isDaemon) 创建一个新的定时器,其相关线程可以指定为 run as a daemon 。

    Timer(String name) 创建一个新的定时器,其相关线程具有指定的名称。

    Timer(String name, boolean isDaemon) 创建一个新的定时器,其相关线程具有指定的名称,可以指定为 run as a daemon 。

    若指定为守护进程有什么效果呢?

    //将上面程序的new Timer时候传入参数true
    Timer timer=new Timer(true);
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Bduindu-1603163485911)(https://i.imgur.com/fVjH9hl.png)]

    因为是守护进程,main线程结束,所以不会执行直接结束。

    ###方法

    void cancel() 终止此计时器,丢弃任何当前计划的任务,将任务队列中的全部任务清空。

    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TestTimer {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("我执行了" + "  " + System.currentTimeMillis());
            }
        }, 1000, 2000);
    
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        timer.cancel();
    
    }
    }
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-POqEAnyC-1603163485913)(https://i.imgur.com/zFGIz4S.png)]


    TimerTask类中的cancel()方法将自身从任务队列中清除。

    	final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        TimerTask timerTaskTwo = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Two运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask,1000,2000);
        timer.schedule(timerTaskTwo,1000,2000);
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        timerTaskTwo.cancel();
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NKFbh4ZE-1603163485914)(https://i.imgur.com/bhVJWyD.png)]


    void schedule(TimerTask task, Date time) 在指定的时间安排指定的任务执行。

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TestTimer {
    public static void main(String[] args) throws ParseException {
        final Timer timer = new Timer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //时间已经过去
        String dateString = "2018-06-19 21:19:00";
        String dateStringTwo = "2018-06-19 21:28:00";
        Date date = dateFormat.parse(dateString);
        Date dateTwo = dateFormat.parse(dateStringTwo);
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        TimerTask timerTaskTwo = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, date);
        timer.schedule(timerTaskTwo, dateTwo);
    
    }
    }
    

    结果:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tBqCpxMZ-1603163485915)(https://i.imgur.com/45AwwmH.png)]

    已经过去的时间一运行就执行任务,而未到达的时间等到达后执行任务。

    为什么程序执行完还不结束?

    这是因为系统默认当 Timer 运行结束后,如果没有手动终止,那么则只有当系统的垃圾收集被调用的时候才会对其进行回收终止。或调用 Timer 类自带的 cancel() 方法,实现 Timer 的终止。


    void schedule(TimerTask task, Date firstTime, long period)从指定的时间开始 ,对指定的任务执行重复的 固定延迟执行 。

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TestTimer {
    public static void main(String[] args) throws ParseException {
        final Timer timer = new Timer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //时间已经过去
        String dateString = "2018-06-19 21:44:40";
        Date date = dateFormat.parse(dateString);
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, date,2000);
    
    }
    }
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HxiRSy7C-1603163485916)(https://i.imgur.com/dkgaGhK.png)]


    void schedule(TimerTask task, long delay) 在指定的延迟之后安排指定的任务执行。

    	final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, 2000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUfxUwXe-1603163485917)(https://i.imgur.com/R4pUZ9z.png)]


    void schedule(TimerTask task, long delay, long period) 在指定的延迟之后开始 ,重新执行固定延迟执行的指定任务。

    	final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, 3000,2000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ax2hsuTe-1603163485918)(https://i.imgur.com/7K7V4a6.png)]


    void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 从指定的时间开始 ,对指定的任务执行重复的固定速率执行 。

        final Timer timer = new Timer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //时间已经过去
        String dateString = "2018-06-19 21:44:40";
        Date date = dateFormat.parse(dateString);
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        //timer.schedule(timerTask, date,2000);
        timer.scheduleAtFixedRate(timerTask, date,2000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JM5fW488-1603163485918)(https://i.imgur.com/4xecFcR.png)]

    之前未执行的任务都被执行了。

    改为

    timer.schedule(timerTask, date,2000);
    //timer.scheduleAtFixedRate(timerTask, date,2000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOjdBDf4-1603163485919)(https://i.imgur.com/Vsy5G1Z.png)]
    之前未执行的任务都被没有被执行。


    void scheduleAtFixedRate(TimerTask task, long delay, long period) 在指定的延迟之后开始 ,重新执行固定速率的指定任务。

    	final Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("运行了,现在" + new Date());
            }
        };
        timer.scheduleAtFixedRate(timerTask, 3000,2000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VBC7FoLQ-1603163485920)(https://i.imgur.com/3kiRXfl.png)]


    ##源码探索

    若创建了无参对象 new Timer() ,查看 Timer 无参构造器:

    public Timer() {
        this("Timer-" + serialNumber());
    }
    

    这边调用 Timer(String name) 构造器,查看 serialNumber() 方法

    /**
     * This ID is used to generate thread names.
     */
    //初始化从 0 开始
    private final static AtomicInteger nextSerialNumber = new AtomicInteger(0);
    private static int serialNumber() {
    	//返回值后加 1
        return nextSerialNumber.getAndIncrement();
    }
    

    验证:

     	Timer timer = new Timer();
        Timer timerTwo = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
                System.out.println("运行了,现在" + new Date());
            }
        };
        TimerTask timerTaskTwo = new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
                System.out.println("Two运行了,现在" + new Date());
            }
        };
        timer.schedule(timerTask, 1000);
        timerTwo.schedule(timerTaskTwo, 1000);
    

    结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9Wp6fHk-1603163485920)(https://i.imgur.com/ZxKsUBX.png)]

    查看 Timer(String name)

    public Timer(String name) {
        thread.setName(name);
        thread.start();
    }
    

    查看 thread

    private final TaskQueue queue = new TaskQueue();
    
    private final TimerThread thread = new TimerThread(queue);
    

    TaskQueue 任务队列用来存放任务即TimerTask,thread来跑任务。


    ###查看 TimerThread 类

    boolean newTasksMayBeScheduled = true;
    

    newTasksMayBeScheduled 用于控制当queue任务队列为空时,定时线程是否应该立刻终止(false立刻终止)

    private TaskQueue queue;
    

    queue 任务队列。

    public void run() {
        try {
    		//最核心
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }
    

    最核心

    private void mainLoop() {
        while (true) {
            try {
                TimerTask task;
                boolean taskFired;
    			// 获取任务队列的锁
                synchronized(queue) {
    				// 如果任务队列为空,并且线程没有被cancel()
                	// 则线程等待queue锁,queue.wait()方法会释放获得的queue锁
                	// 这样在Timer中sched()方法才能够获取到queue锁
                    while (queue.isEmpty() && newTasksMayBeScheduled)
                        queue.wait();
                    if (queue.isEmpty())
                        break; // Queue is empty and will forever remain; die
    
                    // Queue nonempty; look at first evt and do the right thing
                    long currentTime, executionTime;
                    task = queue.getMin();
                    synchronized(task.lock) {
                        if (task.state == TimerTask.CANCELLED) {
                            queue.removeMin();
                            continue;  // No action required, poll queue again
                        }
                        currentTime = System.currentTimeMillis();
                        executionTime = task.nextExecutionTime;
                        if (taskFired = (executionTime<=currentTime)) {
    						// 任务应该被触发,并且不是重复任务
                        	// 将任务从队列中移除并修改任务的执行状态
                            if (task.period == 0) { // Non-repeating, remove
                                queue.removeMin();
                                task.state = TimerTask.EXECUTED;
                            } else { 
    							// 任务是重复执行任务,计算任务下一次应该被执行的时间,并重新排序任务队列
                                queue.rescheduleMin(
                                  task.period<0 ? currentTime   - task.period
                                                : executionTime + task.period);
                            }
                        }
                    }
                    if (!taskFired) // Task hasn't yet fired; wait
                        queue.wait(executionTime - currentTime);
                }
                if (taskFired)  // Task fired; run it, holding no locks
                    task.run();
            } catch(InterruptedException e) {
            }
        }
    }
    

    到这里你会发现为什么正常情况下Timer运行完任务后一直不结束因为一直是while(true) 除非遇到不能捕获的异常或break才会跳出。

    if (queue.isEmpty())
        break;
    

    如果是设置了newTasksMayBeScheduled状态为false跳出,也就是调用了cancel,那么queue就是空的,此时就直接跳出外部的死循环,所以cancel就是这样实现的。


    Timer类中sched方法

    下面所有的 schedule 方法都调用了sched方法

    void schedule(TimerTask task, long delay)

    void schedule(TimerTask task, Date time)

    void schedule(TimerTask task, long delay, long period)

    void schedule(TimerTask task, Date firstTime, long period)

    void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

    void scheduleAtFixedRate(TimerTask task, long delay, long period)

    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
    
        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;
    
        synchronized(queue) {
    		//判断Timer是否已经取消
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");
    
            synchronized(task.lock) {
    			//TimerTask.VIRGIN标记任务没有被调度
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
    			//下一次执行时间
                task.nextExecutionTime = time;
    			//时间片
                task.period = period;
    			//标记这个任务被安排执行
                task.state = TimerTask.SCHEDULED;
            }
    
            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }
    

    为什么要做notify操作呢?

    因为mainLoop()里面的wait()。


    Timer类中cancel方法

    public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
    

    修改newTasksMayBeScheduled为false,删除queue队列中的任务


    ###查看TaskQueue类

    private TimerTask[] queue = new TimerTask[128];
    

    TimerTask数组,初始数组大小为128。

    int size() {
        return size;
    }
    

    size()任务队列的长度

     void add(TimerTask task) {
        // Grow backing store if necessary
        if (size + 1 == queue.length)
    		//扩2倍长度
            queue = Arrays.copyOf(queue, 2*queue.length);
    
        queue[++size] = task;
        fixUp(size);
    }
    

    add(TimerTaskt)为增加一个任务

    TimerTask getMin() {
        return queue[1];
    }
    

    getMin()获取当前排序后最近需要执行的一个任务,下标为1,队列头部0是不做任何操作的

     TimerTask get(int i) {
        return queue[i];
    }
    

    get(int i)获取指定下标的数据,当然包括下标 0

    void removeMin() {
        queue[1] = queue[size];
        queue[size--] = null;  // Drop extra reference to prevent memory leak
        fixDown(1);
    }
    

    removeMin()为删除当前最近执行的任务,也就是第一个元素,通常只调度一次的任务,在执行完后,调用此方法,就可以将TimerTask从队列中移除。

    void quickRemove(int i) {
        assert i <= size;
    
        queue[i] = queue[size];
        queue[size--] = null;  // Drop extra ref to prevent memory leak
    }
    

    quickRmove(int i) 删除指定的元素,一般来说是不会调用这个方法的,这个方法只有在 Timer 发生 purge 的时候,并且当对应的 TimerTask调用了 cancel 方法的时候,才会被调用这个方法,也就是取消某个TimerTask,然后就会从队列中移除(注意如果任务在执行中是,还是仍然在执行中的,虽然在队列中被移除了),还有就是这个 cancel 方法并不是 Timer 的 cancel 方法而是 TimerTask,一个是调度器的,一个是单个任务的,最后注意,这个 quickRmove 完成后,是将队列最后一个元素补充到这个位置,所以此时会造成顺序不一致的问题,后面会有方法进行回补。

    void rescheduleMin(long newTime) {
        queue[1].nextExecutionTime = newTime;
        fixDown(1);
    }
    

    rescheduleMin(long newTime)是重新设置当前执行的任务的下一次执行时间,并在队列中将其从新排序到合适的位置,而调用的是后面说的fixDown方法。

    boolean isEmpty() {
        return size==0;
    }
    

    isEmpty() 判空。

    void clear() {
        // Null out task references to prevent memory leak
        for (int i=1; i<=size; i++)
            queue[i] = null;
    
        size = 0;
    }
    

    clear() 清理。

    对于 fixUp(int k) 和 fixDown(int k) 方法来讲,前者是当新增一个task的时候,首先将元素放在队列的尾部,然后向前找是否有比自己还要晚执行的任务,如果有,就将两个任务的顺序进行交换一下。而fixDown正好相反,执行完第一个任务后,需要加上一个时间片得到下一次执行时间,从而需要将其顺序与后面的任务进行对比下。

    heapify(),其实就是将队列的后半截,全部做一次fixeDown的操作,这个操作主要是为了回补quickRemove方法,当大量的quickRmove后,顺序被打乱后,此时将一半的区域做一次非常简单的排序即可。


    ###TimerTask抽象类

    //对象锁
    final Object lock = new Object();
    
    //task状态初始VIRGIN
    int state = VIRGIN;
    
    //这项任务尚未安排好
    static final int VIRGIN = 0;
    
    //这个任务计划执行。如果它是一个非重复的任务,那么它还没有被执行
    static final int SCHEDULED   = 1;
    
    //此非重复任务已经执行(或目前正在执行)并没有被取消。
    static final int EXECUTED    = 2;
    
    //此任务被取消了
    static final int CANCELLED   = 3;
    
    //任务下次执行时间
    long nextExecutionTime;
    
    //重复任务的周期(毫秒)。一个积极的值表示固定利率执行。负值表示固定延迟执行。值为0表示非重复任务。
    long period = 0;
    
    //取消任务
    public boolean cancel()
    
    //计划执行时间
    public long scheduledExecutionTime() {
        synchronized(lock) {
            return (period < 0 ? nextExecutionTime + period
                               : nextExecutionTime - period);
        }
    }
    

    #总结

    参考
    Java多线程编程核心技术
    https://blog.csdn.net/xieyuooo/article/details/8607220
    https://www.jianshu.com/p/58a5b0853451

    Timer类其实内部有个thread,还有一个queue(来存储task),task会按一定的方式将任务排队处理,thread中的run方法无限循环task队列,执行task中的run()。

    才学疏浅,有什么问题请大家指出来。十分感谢!

    展开全文
  • STM32的通用定时器Timer(库函数),亲测可用,内有详细代码注释和说明讲解,很好的学习资料。
  • NULL 博文链接:https://cfan1874.iteye.com/blog/1765433
  • 主要给大家介绍了关于C++定时器Timer在项目中的基本使用方法,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • STM32的通用定时器Timer(直接操作寄存器),亲测可用,内有详细代码注释和说明讲解,很好的学习资料。
  • 本篇文章主要介绍了java多线程之定时器Timer的使用详解,Time类主要负责完成定时计划任务的功能,有兴趣的可以了解一下。
  • 本文介绍了Android定时器Timer的停止和重启实现代码,分享给大家,具体如下: 7月份做了一个项目,利用自定义控件呈现一幅动画,当时使用定时器来控制时间,但是当停止开启时总是出现问题。一直在寻找合理的方法...
  • React Native实现了和浏览器一致的定时器Timer。 提供的方法如下: setTimeout, clearTimeout setInterval, clearInterval setImmediate, clearImmediate requestAnimationFrame, cancelAnimationFrame set
  • Java定时器Timer简述

    2020-08-31 16:39:28
    本文主要介绍了Java定时器Timer的相关知识,具有一定的参考价值,下面跟着小编一起来看下吧
  • 主要介绍了python线程定时器Timer实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Java定时器Timer简述.pdf

    2021-09-30 17:29:44
    Java定时器Timer简述.pdf
  • 高精度定时器Timer

    2019-04-03 17:00:58
    精度可以准确到1ms 误差不超2ms 相比系统的那个不稳定的定时器有很大改善 修正了Win10下报错问题
  • 主要为大家详细介绍了Java定时器Timer的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • TIA博途中编写的定时器Timer为什么不工作?
  • 主要介绍了C#中的定时器Timer类及其垃圾回收机制,讲解了Timer相关的单线程异步工作,需要的朋友可以参考下
  • 主要介绍了Java多线程定时器Timer原理及实现,涉及Timer的schedule的使用,定时器Timer的schedule等相关内容以及代码示例,具有一定参考价值,需要的朋友可以了解下。
  • C#使用定时器Timer

    2017-02-10 10:59:05
    举例定时器使用,适合快速上手
  • 主要介绍了python通过线程实现定时器timer的方法,涉及Python线程与定时器timer的使用技巧,需要的朋友可以参考下
  • Android定时器Timer简单使用

    千次阅读 2021-10-25 09:45:33
    Android定时器Timer简单使用Timer简介Timer使用总结 Timer简介 Timer(计时器)位于 java.util包下,可用于创建定时任务,任务可以安排为一次性执行,也可以定期重复执行。每个计时器对象对应一个后台线程...

    Android定时器Timer简单使用

    Timer简介

    Timer(计时器)位于 java.util包下,可用于创建定时任务,任务可以安排为一次性执行,也可以定期重复执行。每个计时器对象对应一个后台线程(TimerThread)。简单理解为创建Timer对象,对应TimerThread线程循环开始从TaskQueue队列中执行一个TimerTask任务。

    Timer使用

    1. 创建Timer对象

      var timer = Timer()
      
    2. 添加需要执行的任务

      // 创建计时器对象
      var timer = Timer() 
      // 创建计时器任务
      var timerTask: TimerTask = object : TimerTask() {
      	override fun run(){
      		Log.i("Timer", "定时器执行一次")
      	}
      }
      // 添加任务,设定开始计时器时间,第2个参数为时间单位毫秒,如果是0,立即执行
      timer.schedule(timerTask, 5000)
      

      执行以上代码,可以从控制台看到打印 定时器执行一次,以上代码适用于一次性任务的执行,如启动页定时跳转到首页。

    3. 循环执行任务

      var timer = Timer() 
      // 创建计时器任务
      var timerTask: TimerTask = object : TimerTask() {
      	override fun run(){
      		Log.i("Timer", "定时器执行一次")
      	}
      }
      // 添加任务,设定开始计时器时间,第2个参数为0,立即执行,第3个参数为循环周期间隔为5s
      timer.schedule(timerTask, 0, 5000)
      

      这里需要注意下,第2个参数启动定时器时间为0,代表立即启动,相应的任务会被立即执行,第3个参数为周期间隔5s,对应每5s后执行一次任务。

    4. 取消任务

      var timer = Timer()
      timer.cancel() // 取消任务
      

    总结

    以上就是简单使用计时器(Timer)的例子,可以结合自身需求使用,这里需要注意的是,循环使用时,记得在不需要执行的时候取消任务执行,避免出现内存泄露相关的问题。

    展开全文
  • 主要介绍了java定时器timer的使用方法代码示例,向大家分享了两部分代码,详细内容请参见正文,还是比较不错的,需要的朋友可以参考下。
  • MATLAB中定时器Timer的使用

    千次阅读 2020-10-22 17:54:05
    传送门1-timer 类 传送门2-计时器回调函数 传送门3-使用计时器安排命令的执行 四种定时模式: sigleShot:只执行一次,故Period属性不起作用,其他模式都可以执行多次 fixedDelay:上一次TimerFcn执行完毕时刻...

    使用方法

    具体参考官方文档:

    四种定时模式:

    • sigleShot:只执行一次,故Period属性不起作用,其他模式都可以执行多次

    • fixedDelay:上一次TimerFcn执行完毕时刻到下一次TimerFcn被加入队列时刻之间的间隔

    • fixedRate:上一次开始执行到下一次被加入队列之间的间隔

    • fixedSpacing:前后两次被加入到执行语句队列时刻之间的间隔

    法1:

    timer_id = timer;:
    timer_id.StartDelay = 1.0;
    timer_id.Period = 1.0;
    timer_id.ExecutionMode = 'fixedSpacing';
    timer_id.TimerFcn = @timer_handler;
    start(timer_id);
    
    function timer_handler(~,~)
    	% user code
    end
    

    注意:MATLAB是解释性语言,如果定时器运行中继续启动仿真,会导致同样功能的新定时器启动,且ID号不同属于不同线程!所以重新仿真前应该停止所有定时器并删除!

    法2:

    t = timer('StartDelay',1,'TimerFcn',@t_TimerFcn,'Period',2,'ExecutionMode','fixedRate');
    start(t)
    
    function t_TimerFcn(hObject,eventdata)
    	% user code
    end
    

    应用实例

    案例1:

    % 代码来源:https://zhuanlan.zhihu.com/p/136570344
    
    % 启动定时器
    clear all;
    clc;
    % 删除现有的定时器,重新创建一个定时器
    %stop(timerfind);
    %delete(timerfind);   
    timer_id = timer;
    timer_id.StartDelay = 1.0;
    timer_id.Period = 1.0;
    % 周期性执行,fixedSpacing模式
    timer_id.ExecutionMode = 'fixedSpacing';
    timer_id.TimerFcn = @timer_handler;
    %启动定时器
    start(timer_id);
    
    function timer_handler(~,~)
        persistent counter;
        if isempty(counter)
         counter = 0;
        end
        fprintf(1,'定时器回调=%d\n',counter);
        counter = counter+1;
    end
    

    案例2:

    % 代码来源:https://blog.csdn.net/superjunenaruto/article/details/54614569
    
    %%  定时器
    % 函数说明:(命令行输入)
    % t_test:创建一个定时器对象,从 0 开始计数(每 2 秒)
    % t_test('stop'):停止计数,删除定时器
    function t_test(varargin)
        global num num1 num2
        if nargin == 0  % 直接命令行输入 t_test 表示:创建一个定时器对象,开始定时
            num = 0;
            num1 = 100;
            num2 = 1000;
            delete(timerfind)   % 删除现有的定时器,重新创建一个定时器
            t = timer('StartDelay',1,'TimerFcn',@t_TimerFcn,'Period',2,'ExecutionMode','fixedRate');
            t1 = timer('StartDelay',1,'TimerFcn',@t_TimerFcn1,'Period',2,'ExecutionMode','fixedDelay');
            t2 = timer('StartDelay',1,'TimerFcn',@t_TimerFcn2,'Period',2,'ExecutionMode','fixedSpacing');
            start([t,t1,t2])
        elseif ((nargin == 1) && strcmp(varargin{1},'stop'))
            stop(timerfind)
            delete(timerfind)
        else
            
        end
    end
    %%  回调函数
    function t_TimerFcn(hObject,eventdata)
        global num
        disp(num2str(num))
        num = num + 1;
    end
    function t_TimerFcn1(~,~)
        global num1
        disp(num2str(num1))
        num1 = num1 + 1;
    end
    function t_TimerFcn2(~,~)
        global num2
        disp(num2str(num2))
        num2 = num2 + 1;
    end
    
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 145,490
精华内容 58,196
关键字:

定时器timer

友情链接: 1208LS采集练习.zip