java之定时器

就性能而言 当周期在一分钟之内时 最好用线程 (添加异常保护) ,一分钟以后的再用定时器


 

java Timer 的 schedule 和 scheduleAtFixedRate 方法的区别


API:
schedulepublic void schedule( task,     long delay)
安排在指定延迟后执行指定的任务。
参数:task - 所要安排的任务。delay - 执行任务前的延迟时间,单位是毫秒。
抛出: - 如果 delay 是负数,或者 delay + System.currentTimeMillis() 是负数。 - 如果已经安排或取消了任务,或者已经取消计时器。
 
schedulepublic void schedule( task,    time)
安排在指定的时间执行指定的任务。如果此时间已过去,则安排立即执行该任务。
参数:task - 所要安排的任务。time - 执行任务的时间。
抛出: - 如果 time.getTime() 是负数。 - 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。
 
schedulepublic void schedule( task  ,      long delay,    long period)
安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。
在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。从长期来看,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
固定延迟执行适用于那些需要“平稳”运行的重复活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。
参数:task - 所要安排的任务。delay - 执行任务前的延迟时间,单位是毫秒。period - 执行各后续任务之间的时间间隔,单位是毫秒。
抛出: - 如果 delay 是负数,或者 delay + System.currentTimeMillis() 是负数。 - 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。
 

schedulepublic void schedule( task,    firstTime, long period)

安排指定的任务在指定的时间开始进行重复的固定延迟执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定延迟执行中,根据前一次执行的实际执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则后续执行也将被延迟。在长期运行中,执行的频率一般要稍慢于指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
固定延迟执行适用于那些需要“平稳”运行的重复执行活动。换句话说,它适用于在短期运行中保持频率准确要比在长期运行中更为重要的活动。这包括大多数动画任务,如以固定时间间隔闪烁的光标。这还包括为响应人类活动所执行的固定活动,如在按住键时自动重复输入字符。
参数:task - 所要安排的任务。firstTime - 首次执行任务的时间。period - 执行各后续任务之间的时间间隔,单位是毫秒。
抛出: - 如果 time.getTime() 是负数。 - 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。
 

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

安排指定的任务在指定的延迟后开始进行重复的固定速率执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。

在固定速率执行中,根据已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他背景活动)而延迟了某次执行,则将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”。从长远来看,执行的频率将正好是指定周期的倒数(假定 Object.wait(long) 所依靠的系统时钟是准确的)。
固定速率执行适用于那些对绝对 时间敏感的重复执行活动,如每小时准点打钟报时,或者在每天的特定时间运行已安排的维护活动。它还适用于那些完成固定次数执行的总计时间很重要的重复活动,如倒计时的计时器,每秒钟滴答一次,共 10 秒钟。最后,固定速率执行适用于安排多个重复执行的计时器任务,这些任务相互之间必须保持同步。
参数:task - 所要安排的任务。delay - 执行任务前的延迟时间,单位是毫秒。period - 执行各后续任务之间的时间间隔,单位是毫秒。
抛出: - 如果 delay 是负数,或者 delay + System.currentTimeMillis() 是负数。 - 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。
 
scheduleAtFixedRatepublic void scheduleAtFixedRate( task,     firstTime,    long period)
安排指定的任务在指定的时间开始进行重复的固定速率执行。以近似固定的时间间隔(由指定的周期分隔)进行后续执行。
在固定速率执行中,相对于已安排的初始执行时间来安排每次执行。如果由于任何原因(如垃圾回收或其他背景活动)而延迟了某次执行,则将快速连续地出现两次或更多次执行,从而使后续执行能够赶上来。从长远来看,执行的频率将正好是指定周期的倒数(假定Object.wait(long) 所依靠的系统时钟是准确的)。
固定速率执行适用于那些对绝对 时间敏感的重复执行活动,如每小时准点打钟报时,或者在每天的特定时间运行已安排的维护活动。它还适用于那些完成固定次数执行的总计时间很重要的重复活动,如倒计时的计时器,每秒钟滴答一次,共 10 秒钟。最后,固定速率执行适用于安排多次重复执行的计时器任务,这些任务相互之间必须保持同步。
参数:task - 所要安排的任务。firstTime - 首次执行任务的时间。period - 执行各后续任务之间的时间间隔,单位是毫秒。
抛出: - 如果 time.getTime() 是负数。 - 如果已经安排或取消了任务,已经取消了计时器,或者计时器线程已终止。
 
区别:
网络版A:
schedule和scheduleAtFixedRate的区别在于,如果指定开始执行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上。
  比如
  SimpleDateFormat fTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
  Date d1 = fTime.parse("2005/12/30 14:10:00");
  t.scheduleAtFixedRate(new TimerTask(){
  public void run()
  {
  System.out.println("this is task you do6");
  }
  },d1,3*60*1000);
  间隔时间是3分钟,指定开始时间是2005/12/30 14:10:00,如果我在14:17:00分执行这个程序,那么会立刻打印3次
  this is task you do6     //14:10
  this is task you do6     //14:13
  this is task you do6     //14:16
  并且注意,下一次执行是在14:19 而不是 14:20。就是说是从指定的开始时间开始计时,而不是从执行时间开始计时。
  但是上面如果用schedule方法,间隔时间是3分钟,指定开始时间是2005/12/30 14:10:00,那么在14:17:00分执行这个程序,则立即执行程序一次。并且下一次的执行时间是 14:20,而不是从14:10开始算的周期(14:19)。
  需要注意的是scheduleAtFixedRate和schedule在参数完全相同的情况下,执行效果是不同的。上面例子中任务只是打印一个字符串,比较简单。但如果任务比较复杂,或者由于任何原因(如垃圾回收或其他后台活动)而延迟了某次执行,则scheduleAtFixedRate方法将快速连续地出现两次或更多的执行,从而使后续执行能够“追赶上来”;而schedule方法的后续执行也将被延迟。所以,在长期运行中,scheduleAtFixedRate执行的频率将正好是指定周期的倒数,schedule 执行的频率一般要稍慢于指定周期的倒数。
  scheduleAtFixedRate 效率总体上高于schedule。
----------------------------------------------------------------------------------------END A
关于A版本的最后一句话,原因是他们的另一个区别:
 
网络版B:
在java中,Timer类主要用于定时性、周期性任务 的触发,这个类中有两个方法比较难理解,那就是schedule和scheduleAtFixedRate方法,在这里就用实例分析一下

(1)schedule方法:“fixed-delay”;如果第一次执行时间被delay了,随后的执行时间按 照 上一次 实际执行完成的时间点 进行计算

(2)scheduleAtFixedRate方法:“fixed-rate”;如果第一次执行时间被delay了,随后的执行时间按照 上一次开始的 时间点 进行计算,并且为了”catch up”会多次执行任务,TimerTask中的执行体需要考虑同步

[c-sharp] view plaincopyprint?

1.     SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  
2.     Date startDate = dateFormatter.parse("2010/11/26 00:20:00");  
3.     Timer timer = new Timer();  
4.     timer.scheduleAtFixedRate(new TimerTask(){  
5.        public void run()  
6.        {  
7.            System.out.println("execute task!" + this.scheduledExecutionTime());  
8.        }  
9.     },startDate,3*60*1000);  

以上的代码,表示在2010-11-26 00:20:00秒开始执行,每3分钟执行一次
假设在2010/11/26 00:27:00执行
以上会打印出3次
execute task!   00:20
execute task!   00:23    catch up
execute task!   00:26    catch up
下一次执行时间是00:29,相对于00:26
当换成schedule方法时,在2010/11/26 00:27:00执行
会打印出1次
execute task!   00:20   无catch up
下一次执行时间为00:30,相对于00:27


以上考虑的都是在你设定的timer开始时间后,程序才被执行


当执行任务的时间大于周期间隔时,会发生什么呢?
(1)schedule方法:下一次执行时间相对于 上一次 实际执行完成的时间点 ,因此执行时间会不断延后
(2)scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的 时间点 ,因此执行时间不会延后,存在并发性
以下例程序来测试上述结论,TimerTask需要执行6秒钟,但是间隔周期为5秒钟


[java] view plaincopyprint?


1.    package test;  
2.    import java.text.ParseException;  
3.    import java.text.SimpleDateFormat;  
4.    import java.util.Date;  
5.    import java.util.Timer;  
6.    import java.util.TimerTask;  
7.    public class Test {  
8.          
9.        public static void main(String[] args) throws ParseException {  
10.         SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  
11.         Date startDate = dateFormatter.parse("2010/11/28 01:06:00");  
12.         Timer timer = new Timer();  
13.         timer.schedule(new TimerTask(){  
14.            public void run() {  
15.                try {  
16.                    Thread.sleep(6000);  
17.                } catch (InterruptedException e) {  
18.                    e.printStackTrace();  
19.                }  
20.                System.out.println("execute task!"+ this.scheduledExecutionTime());  
21.            }  
22.         },startDate, 5 * 1000);  
23.     }  
24.       
25. }  



 

java 定时器的使用

 如果定时调用很频繁,另起线程sleep比较好,一般半分钟以上 用定时,半分钟以下sleep。

    简单的用定时器比较好,定时器准确来说定时效果不好,程序占用资源比较多,特别是多个定时器时;复杂的程序用线程好,特别是多线程,使用线程可以优化资源,提高效率。不过没有具体的优劣,要看具体情况。

       定时器类Timer在java.util包中。使用时,先实例化,然后使用实例的schedule(TimerTask task, long delay)方法,设定指定的任务task在指定的延迟delay后执行。定时器任务类TimerTask是抽象类,继承并重写其run()方法,可实现具体任务。

schedule(TimerTask task, Date time)设定指定任务task在指定时间time执行。

cancel()方法结束这个定时器。

schedule(TimerTask task, long delay, long period)方法设定指定任务task在指定延迟delay后进行固定延迟peroid的执行。

scheduleAtFixedRate(TimerTask task, long delay, long period)方法设定指定任务task在指定延迟delay后进行固定频率peroid的执行。

要实现一个定时任务,运用java中的Timer和TimerTask类可以非常容易实现实时调用处理函数。这两个类使用起来非常方便,可以完成我们对定时器的绝大多数需要。

看个简单的例子:

import java.io.IOException;
import java.util.Timer;

public class TimerTest {

public static void main(String[] args){
Timer timer = new Timer();
timer.schedule(new MyTask(), 1000, 2000);//在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
while(true){//这个是用来停止此任务的,否则就一直循环执行此任务了
try {
int ch = System.in.read();
if(ch-'c'==0){
timer.cancel();//使用这个方法退出任务
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

static class MyTask extends java.util.TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("________");
}
}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值