timer 订阅
Timer
信息
操作系统
未知
开发语言
开源协议
未知
Timer
Timer is an extension that is loosely based on Prototype's PeriodicalExecuter . The three main enhancements are: * It's for jQuery (1.1.x and 1.2.x) * Timer intervals can be reset during the event * It's a much shorter name
收起全文
精华内容
下载资源
问答
  • timer

    千次阅读 2017-12-19 17:32:41
    Faster R-CNN中提供了一个很好用的python下计时工具,用于分析模型运行速度的...import timeclass Timer(object): """A simple timer.""" def __init__(self): self.total_time = 0. self.calls = 0 self.start_

    Faster R-CNN中提供了一个很好用的python下计时工具,用于分析模型运行速度的评估。

    import time
    
    class Timer(object):
        """A simple timer."""
        def __init__(self):
            self.total_time = 0.
            self.calls = 0
            self.start_time = 0.
            self.diff = 0.
            self.average_time = 0.
    
        def tic(self):
            # using time.time instead of time.clock because time time.clock
            # does not normalize for multithreading
            self.start_time = time.time()
    
        def toc(self, average=True):
            self.diff = time.time() - self.start_time
            self.total_time += self.diff
            self.calls += 1
            self.average_time = self.total_time / self.calls
            if average:
                return self.average_time
            else:
                return self.diff

    使用时

    import Timer
    timer = Timer()
    timer.tic() # 单次开始计时
    ...
    timer.toc() # 结束本次计时,返回值可以为多次的平均时间, 也可以为此次时间差toc(average=False)

    注意:

    计算机系统存在两个时间:CPU时间time.clock(),挂钟时间time.time()

    • CPU时间>挂钟时间: 计算密集型任务,通过优化程序并发可以获得更好的效果,包含CPU内核调度时间(sys)和CPU计算时间(user)
    • 挂钟时间≈CPU时间: IO密集型任务,不能通过并发改进性能,

    具体使用参考: Python程序计时

    展开全文
  • Timer

    千次阅读 2012-12-07 21:53:23
    http://blog.csdn.net/elfylin/article/details/7072406 1. Timer.start void TimerBase::start TimerBase::setNextFireTime ThreadTimers::updateSharedTimer SharedTimer::setFireTime MainThreadSh

    http://blog.csdn.net/elfylin/article/details/7072406



    1. Timer.start

    void TimerBase::start
    TimerBase::setNextFireTime
    ThreadTimers::updateSharedTimer
    SharedTimer::setFireTime
    MainThreadSharedTimer::setFireTime
    MainThreadSharedTimer::setSharedTimerFireTime
    TimerClient::setSharedTimer
    JavaBridge::setSharedTimer
    JWebCoreJavaBridge.java::setSharedTimer
    JWebCoreJavaBridge.java::fireSharedTimer
    JWebCoreJavaBridge.java::sharedTimerFired
    JavaBridge::SharedTimerFired
    JavaBridge::sSharedTimerFiredCallback


    2.set firedfunc

    ThreadTimers::sharedTimerFired()/static Vector<TimerBase*>& timerHeap()/TimerBase::setNextFireTime
    ThreadTimers& ThreadGlobalData::threadTimers()
    ThreadTimers::ThreadTimers
    ThreadTimers::setSharedTimer(ThreadTimers::sharedTimerFired)
    MainThreadSharedTimer::setFiredFunction
    setSharedTimerFiredFunction(void (*f)()) (SharedTimerAndroid.cpp)


    ThreadGlobalData has "HashMap<ThreadIdentifier, ThreadTimers* > m_threadTimers"
    ThreadTimer has "Vector<TimerBase*> m_timerHeap"



    3.TimerFired
    ThreadTimers::sharedTimerFired
    threadGlobalData().threadTimers().sharedTimerFiredInternal();
    void ThreadTimers::sharedTimerFiredInternal()
    Timer::fired()
    TimerFiredClass::TimerFiredFunction()

    展开全文
  • 定时器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()。

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

    展开全文
  • 主要介绍了C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析,以实例形式较为详细的讲述了.NET Framework里面提供的三种Timer具体用法,需要的朋友可以参考下
  • Timer定时器用法详解

    万次阅读 多人点赞 2019-07-06 17:30:20
    Timer timer = new Timer(); //其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字 Timer timer = new Timer(String name); //以name作为该定时器的名字 Timer time...

    先看API和结论:

    /**
        timer总结:
        Timer timer = new Timer();    //其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字
        Timer timer = new Timer(String name);    //以name作为该定时器的名字
        Timer timer = new Timer(boolean isDeamon);    //是否将此定时器作为守护线程执行
        Timer timer = new Timer(name, isDeamon);    //定时器名字, 是否为守护线程
        
        注意:
        默认无参构造器将会使该线程作为非守护线程, 即使主线程已经停止并销毁, 只要该线程还存在, 则程序不会停止
        即下面的所有执行的任务, 无论是否是定时还是非定时, 只要主线程一旦结束, 那么该定时器立即同主线程一起销毁
        
        以下所有的task都是TimerTask的子类
        所有time都是Date类型的日期
        所有delay和period都是long类型的延迟时间, 单位为毫秒
        timer.schedule(task, time);                    在time时间执行task任务1次
        timer.schedule(task, delay);                在延迟delay毫秒后执行task任务1次
        timer.schedule(task, firstTime, period);    在firsttime时间执行task1次,之后定期period毫秒时间执行task,    时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
        timer.schedule(task, delay, period);        在延迟delay后执行task1次,之后定期period毫秒时间执行task,     时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
        
        timer.scheduleAtFixedRate(task, firstTime, period);        在firstTime时间执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
        timer.scheduleAtFixedRate(task, delay, period);            在delay毫秒后执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
        
        区别:test4();
        timer.schedule(task, firstTime, period);
        timer.scheduleAtFixedRate(task, firstTime, period);
        从test4运行结果可以看到, 如果开始时间在过去, 则
            schedule会表现出只从当前时间开始,
            scheduleAtFixedRate会把之前没有来得及执行的任务全都执行, 感觉像之前一直有在执行一样
            
        区别: test5()
        timer.schedule(task, time);
        timer.schedule(task, delay);
        其中, 如果time时间为过去时间, 则该任务会马上执行, 如果为将来时间, 则会等待时间到来再执行
        如果传入的是delay, 则delay不可以为负数, 负数报错, 正数代表未来的delay毫秒以后执行
        
        
        小结:
            时间如果为过去时间, 则所有scheduke和scheduleAtFixedRate都会立即执行
            并且scheduke不会执行过去的任务, 而scheduleAtFixedRate则会把过去的任务全都执行, 即按照固定时间执行一样
            isDeamon决定是否该Timer以守护线程存在

        timer.purge();
        先看英文描述:
        Removes all cancelled tasks from this timer's task queue. Calling this method has no effect on the behavior of the timer, but eliminates the references to the cancelled tasks from the queue. If there are no external references to these tasks, they become eligible for garbage collection. 
        Most programs will have no need to call this method. It is designed for use by the rare application that cancels a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the number of cancelled tasks. 
        Note that it is permissible to call this method from within a a task scheduled on this timer.
        Returns:
        the number of tasks removed from the queue.
        Since:
        1.5
        即purge();对实际的timer的任务执行不会有影响, 它仅仅只会移除所有被取消的任务队列的引用以方便垃圾回收, 通常不用调用此方法, 只有任务数非常多(n + c log n)的时候, 可以调用此方法以时间换取空间.
        
        timer.cancel();
        Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it. 
        Note that calling this method from within the run method of a timer task that was invoked by this timer absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this timer. 
        This method may be called repeatedly; the second and subsequent calls have no effect.
        即cancel();停止该timer, 并且丢弃所有绑定的任务, 但不干预当前正在执行的任务。一旦timer停止了, 那么其执行线程将会优雅终止, 并且该timer不可以再绑定task任务了
     */

    再看测试代码:

    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    /**
    	timer总结:
    	Timer timer = new Timer();	//其中会调用this("Timer-" + serialNumber());, 即它以Timer+序列号为该定时器的名字
    	Timer timer = new Timer(String name);	//以name作为该定时器的名字
    	Timer timer = new Timer(boolean isDeamon);	//是否将此定时器作为守护线程执行
    	Timer timer = new Timer(name, isDeamon);	//定时器名字, 是否为守护线程
    	
    	注意:
    	默认无参构造器将会使该线程作为非守护线程, 即使主线程已经停止并销毁, 只要该线程还存在, 则程序不会停止
    	即下面的所有执行的任务, 无论是否是定时还是非定时, 只要主线程一旦结束, 那么该定时器立即同主线程一起销毁
    	
    	以下所有的task都是TimerTask的子类
    	所有time都是Date类型的日期
    	所有delay和period都是long类型的延迟时间, 单位为毫秒
    	timer.schedule(task, time);					在time时间执行task任务1次
    	timer.schedule(task, delay);				在延迟delay毫秒后执行task任务1次
    	timer.schedule(task, firstTime, period);	在firsttime时间执行task1次,之后定期period毫秒时间执行task,	时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
    	timer.schedule(task, delay, period);		在延迟delay后执行task1次,之后定期period毫秒时间执行task, 	时间如果为过去时间, 不会执行过去没有执行的任务, 但是会马上执行
    	
    	timer.scheduleAtFixedRate(task, firstTime, period);		在firstTime时间执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
    	timer.scheduleAtFixedRate(task, delay, period);			在delay毫秒后执行task一次, 以后每隔period毫秒执行1次, 时间如果为过去时间, 会执行过去没有执行的任务, 但是会马上执行
    	
    	区别:test4();
    	timer.schedule(task, firstTime, period);
    	timer.scheduleAtFixedRate(task, firstTime, period);
    	从test4运行结果可以看到, 如果开始时间在过去, 则
    		schedule会表现出只从当前时间开始,
    		scheduleAtFixedRate会把之前没有来得及执行的任务全都执行, 感觉像之前一直有在执行一样
    		
    	区别: test5()
    	timer.schedule(task, time);
    	timer.schedule(task, delay);
    	其中, 如果time时间为过去时间, 则该任务会马上执行, 如果为将来时间, 则会等待时间到来再执行
    	如果传入的是delay, 则delay不可以为负数, 负数报错, 正数代表未来的delay毫秒以后执行
    	
    	
    	小结:
    		时间如果为过去时间, 则所有scheduke和scheduleAtFixedRate都会立即执行
    		并且scheduke不会执行过去的任务, 而scheduleAtFixedRate则会把过去的任务全都执行, 即按照固定时间执行一样
    		isDeamon决定是否该Timer以守护线程存在
    
    	timer.purge();
    	先看英文描述:
    	Removes all cancelled tasks from this timer's task queue. Calling this method has no effect on the behavior of the timer, but eliminates the references to the cancelled tasks from the queue. If there are no external references to these tasks, they become eligible for garbage collection. 
    	Most programs will have no need to call this method. It is designed for use by the rare application that cancels a large number of tasks. Calling this method trades time for space: the runtime of the method may be proportional to n + c log n, where n is the number of tasks in the queue and c is the number of cancelled tasks. 
    	Note that it is permissible to call this method from within a a task scheduled on this timer.
    	Returns:
    	the number of tasks removed from the queue.
    	Since:
    	1.5
    	即purge();对实际的timer的任务执行不会有影响, 它仅仅只会移除所有被取消的任务队列的引用以方便垃圾回收, 通常不用调用此方法, 只有任务数非常多(n + c log n)的时候, 可以调用此方法以时间换取空间.
    	
    	timer.cancel();
    	Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it. 
    	Note that calling this method from within the run method of a timer task that was invoked by this timer absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this timer. 
    	This method may be called repeatedly; the second and subsequent calls have no effect.
    	即cancel();停止该timer, 并且丢弃所有绑定的任务, 但不干预当前正在执行的任务。一旦timer停止了, 那么其执行线程将会优雅终止, 并且该timer不可以再绑定task任务了
    	
    	
     */
    public class TimerTest {
    
    	public static void main(String[] args) {
    //		test1();		//测试schedule功能
    //		test2();		//测试所有scheduleAtFixedRate功能
    //		test3();		//测试isDeamon对Timer的影响
    //		test4();		//测试AtFixedRateSchedule和schedule区别
    //		test5();		//测试schedule在过去时间的表现, 如果firstTime是过去时间, 则立即执行, 如果是未来时间, 则会等待时间到之后执行, 如果是传入延迟时间, 则延迟时间不能为负数, 否则报错
    //		test6();		
    		test7();
    	}
    	
    	public static void test1()
    	{
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了1次");
    			}
    		}, 1000);
    		
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了2次");
    			}
    		}, getDelayTime(2));
    		
    		//第3和第4个task的执行顺序是不确定的,因为时间片的切换导致的微小差别
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("执行了3次");
    			}
    		}, getDelayTime(3), 1000);	//3, -3
    		
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.err.println("执行了4次");
    			}
    		}, 1000, 1000);
    	}
    	public static void test2()
    	{
    		Timer timer = new Timer();
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("AtFixedRate1");
    			}
    		}, getDelayTime(1), 1000);
    		
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("AtFixedRate2");
    			}
    		}, 2000, 1000);
    	}
    	
    	public static void test3()
    	{
    		Timer timer = new Timer("isDeamon", true);
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("isDeamon");
    				try {
    					Thread.sleep(10000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}, getDelayTime(2), 2000);
    	}
    	
    	public static void test4()
    	{
    		Timer timer = new Timer("AtFixedRate", false);
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("schedule");
    			}
    		}, getDelayTime(-5), 2000);
    		
    		timer.scheduleAtFixedRate(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("scheduleAtFixedRate");
    			}
    		}, getDelayTime(-5), 2000);
    	}
    	
    	public static void test5()
    	{
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试时间为过去时间和将来时间对schedule的影响");
    			}
    		}, getDelayTime(-5));	//立即执行
    	}
    	
    	public static void test6()
    	{
    		//purge: 清洗, 净化
    		Timer timer = new Timer();
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试purge1");
    			}
    		}, getDelayTime(1), 1000);
    		System.out.println("purge: "+timer.purge());
    		timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("测试purge2");
    			}
    		}, getDelayTime(1), 1000);
    	}
    	
    	public static void test7()
    	{
    		//将7和6对比看
    		Timer timer = new Timer();
    		class MyTimerTask extends TimerTask{
    			@Override
    			public void run() {
    				System.out.println("测试purge1");
    				this.cancel();
    			}
    		}
    		for(int i = 0; i<100; i++)
    		{
    			MyTimerTask mt = new MyTimerTask();
    			timer.schedule(mt, getDelayTime(1), 1000);
    			mt.cancel();
    		}
    //		timer.cancel();
    		System.out.println("此时可以移除取消的任务数为100个: "+timer.purge());
    		/*timer.schedule(new TimerTask() {
    			@Override
    			public void run() {
    				System.out.println("我现在还可以执行~~");
    			}
    		}, getDelayTime(2));*/
    		
    		
    		for(int i = 0; i<100; i++)
    		{
    			MyTimerTask mt = new MyTimerTask();
    			mt.cancel();
    			timer.schedule(mt, getDelayTime(1), 1000);
    		}
    		System.out.println("此时可以移除取消的任务数为100个: "+timer.purge());
    		///
    	}
    	
    	//给定一个时间,返回给定多久以后的Date
    	public static Date getDelayTime(int howlong)
    	{
    		Calendar cld = Calendar.getInstance();
    		cld.set(Calendar.SECOND, howlong+cld.get(Calendar.SECOND));
    		return cld.getTime();
    	}
    }
    

    其中难点只有这个purge的使用,下面这篇文章详细解释了purge在queue队列非常大时如何避免内存泄漏的

    Java定时任务Timer调度器【三】 注意事项(任务精确性与内存泄漏)

    这里有个问题待考虑:为什么purge()返回值一直是0,我已经将TimerTask任务取消,但是返回的purge()还是0.这点很奇怪。

    其他类似文章:

    定时器Timer

    展开全文
  • 时钟Timer钟表Timer

    2009-07-04 19:20:45
    时钟Timer 时钟Timer 时钟Timer 时钟Timer
  • 在LogFilesHTTPERR的日志中发现了大量Timer_MinBytesPerSecond,Timer_ConnectionIdle错误,这里简单介绍下原因
  • Timer详解

    千次阅读 2019-07-03 12:16:35
    文章目录timer介绍:timer的使用:timer源码分析:生产者代码消费者代码timer的schedule和scheduleAtFixedRate区别:timer的缺点:timer的替代产品: timer介绍: Timer是Josh Bloch在jdk1.3发布的一个新的api,...
  • Timer定时器

    千次阅读 2016-01-06 19:33:31
    JAVA定时器Timer
  • 关于ets_timer与os_timer

    千次阅读 2019-01-07 19:04:14
    在ESP8266 non_os SDK的 osapi.h 中,做了一些关于ets_timer与os_timer的宏定义,但是需要注意一点这两者并不等价。os_timer_disarm() 等价于ets_timer_disarm(), os_timer_setfn()等价于ets_timer_setfn()。但是...
  • 一、Forms.Timer using System.Windows.Forms.Timer; 实现按用户定义的时间间隔引发事件的计时器。此计时器最宜用于 Windows 窗体应用程序中,并且必须在窗口中使用。 这个类在Windows应用程序中使用,用来定期...
  • Java中Timer的用法

    2020-12-22 19:36:50
    timer正好用于此处。  用法很简单,new一个timer,然后写一个timertask的子类即可。  代码如下: package comz.autoupdatefile; import java.util.Timer; import java.util.TimerTask; public class M { ...
  • vp_Timer.zip

    2020-05-21 16:37:38
    vptimer 逻辑层的计时器,安全 高效 节省个人的开发时间 vp_Timer.in vp_Timer.in vp_Timer.in vp_Timer.in
  • Golang timer定时器

    万次阅读 2018-11-05 11:12:45
    Golang timer定时器   timer 计时器 用于在指定的Duration类型时间后调用函数或计算表达式。 如果只是想指定时间之后执行,使用time.Sleep() 使用NewTimer(),可以返回的Timer类型在计时器到期之前,取消该计时器...
  • Timer用法

    千次阅读 2018-07-17 16:12:49
    项目需要,学了一下timer控件,很好用,特此分享。。。 以下是项目界面,详设,以及代码截图 1.项目界面截图 2.详设截图 3.数据和刷新时间代码截图 4.滚动状态代码截图 5.停止滚动代码截图 6.停止取样代码 7....
  • C# Timer

    千次阅读 2016-08-26 22:32:34
    Timer控件主要会用到2个属性一个是Enabled和Interval Enabled主要是控制当前Timer控件是否可用 timer1.Enabled=false;不可用 timer1.Enabled=true;可用 timer1.Interval=1000;主要是设置timer1_Tick事件的时间,...
  • C# Timer详解

    千次阅读 2019-06-27 10:30:10
    在C#中Timer类的定义有四个: System.Threading.Timer System.Windows.Forms.Timer:仅在.NetFramework中 System.Timers.Timer System.Web.UI.Timer:仅在.Net Framework中 System.Windows.Forms.Timer 定时器...
  • 主要介绍了C#中timer定时器用法,实例分析了timer定时器实现定时触发事件的技巧,需要的朋友可以参考下
  • MsTimer2.rar

    2020-05-02 22:50:04
    使用 MsTimer2 定时库可以实现对arduino的定时控制,甚至可以让arduino输出音符。
  • Android 定时器Timer

    千次阅读 2019-07-29 11:00:29
    定义一个定时器,处理handler Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { Thread thread = new Thread(new Runnab...
  • 本文实例讲述了C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析,分享给大家供大家参考。具体分析如下: 在.NET Framework里面提供了三种Timer ① System.Windows.Forms.Timer ② System.Timers...
  • Kotlin中使用Timer

    千次阅读 2020-04-27 20:03:11
    在kotlin中使用Timer执行定时任务. 解决方案 class MainActivity : AppCompatActivity() { lateinit var timer: Timer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceSt.....
  • NSRunLoopCommonModes和TimerNSThread和TimerGCD中的Timer 1. NSRunLoopCommonModes和Timer  当使用NSTimer的scheduledTimerWithTimeInterval方法时。事实上此时Timer会被加入到当前线程的Run Loop中,且...
  • TimerTimer schedule()方法

    千次阅读 2017-05-17 14:28:38
    需要的包是: import java.util.Timer; import java.util.TimerTask;...Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("**********
  • Timer 和 TimerTask 抽象类TimerTask Timer Timer构造函数及方法 示例 Spring对Java Timer的支持 Spring40已经不支持了推荐使用Quartz ScheduledTimerTask MethodInvokingTimerTaskFactoryBean TimerFactoryBean ...
  • C# WPF添加timer,实现Timer事件

    万次阅读 2017-09-14 08:27:25
    C# WPF添加timer 在WPF中不能直接添加timer控件,只能手动自己添加。 namespace CountDown { public partial classMainWin : Window { private DispatcherTimer timer; //设置定时器 timer = new Dispatc
  • DNN 时钟模块Timer

    2011-08-17 15:31:58
    DNN 时钟模块Timer,Timer,Timer,Timer,Timer,Timer

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 421,019
精华内容 168,407
关键字:

timer