java定时器

在应用开发中,经常需要一些周期性的操作,比如每5分钟检查一下新邮件等

。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类

。比如下面的代码每5分钟检查一遍是否有新邮件:
        private java.util.Timer timer;
        timer = new Timer(true);
        timer.schedule(new java.util.TimerTask() {
            public void run() {
                    //server.checkNewMail(); 检查新邮件
            }
        }, 0, 5*60*1000);

使用这几行代码之后,Timer本身会每隔5分钟调用一遍

server.checkNewMail()方法,不需要自己启动线程。Timer本身也是多线程

同步的,多个线程可以共用一个Timer,不需要外部的同步代码。
    在《The Java Tutorial》中有更完整的例子:
public class AnnoyingBeep {
    Toolkit toolkit;
    Timer timer;

    public AnnoyingBeep() {
    toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(),
                   0,        //initial delay
                   1*1000);  //subsequent rate
    }

    class RemindTask extends TimerTask {
    int numWarningBeeps = 3;

        public void run() {
        if (numWarningBeeps > 0) {
            toolkit.beep();
        System.out.println("Beep!");
        numWarningBeeps--;
        } else {
            toolkit.beep();
                System.out.println("Time's up!");
            //timer.cancel(); //Not necessary because we call

System.exit
            System.exit(0);   //Stops the AWT thread (and

everything else)
        }
        }
    }
    ...
}
这段程序,每隔3秒响铃一声,并打印出一行消息。循环3次。程序输出如下


Task scheduled.
Beep!     
Beep!      //one second after the first beep
Beep!      //one second after the second beep
Time's up! //one second after the third beep

Timer类也可以方便地用来作为延迟执行,比如下面的代码延迟指定的时间(

以秒为单位)执行某操作。类似电视的延迟关机功能。
...
public class ReminderBeep {
    ...
    public ReminderBeep(int seconds) {
    toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds*1000);
    }

    class RemindTask extends TimerTask {
        public void run() {
            System.out.println("Time's up!");
        toolkit.beep();
        //timer.cancel(); //Not necessary because we call

System.exit
        System.exit(0);   //Stops the AWT thread (and everything

else)
        }
    }
    ...
}


1. 希望自己的Task一直运行,而不是像上面的RemindTask那样仅循环3次。
这很简单,可能这位朋友把Task的作用理解有误,Task仅代表了一次的动作

。而不是让Task完成循环。上面的RemindTask中之所以有一个计数,是因为

要运行3次停止,如果需要一直保持运行。把上面有关的计数的代码全部去除

即可。其实Timer中并没有提供运行指定次数后即停止的机制,所以,上面的

计数满足了这个功能需要。

2. 能否设置Timer的优先级?
Timer中是利用一个线程来进行计时及周期触发动作的。现在的Timer实现中

并没有提供设置优先级的方法,在你调用new Timer()时线程已经启动,所

以,除非Timer的以后版本中在构造方法中增加优先级参数,否则,我们是不

能控制其优先级的。现在的Timer默认是在Thread.NORM_PRIORITY优先级下运

行的。但是Timer提供了一个Timer(boolean isDaemon)的构造方法,可以将

Timer设置为daemon线程。这样,在你的程序中其它线程都运行完毕后,程序

就可以退出了。

3. Timer是不是实现了精确地定时?
否。Timer中也是采用Object.wait(long time)来实现定时的,由于

Object.wait()不保证精确计时,所以Timer也不是一个精确的时钟。如果是

实时系统,不能依赖Timer。

4. (liangyiqing)假如我在一个Timer类里面再定义一个Timer类,如果外

层定义的时间是24小时循环一次,而内层定义的是1小时循环一次,意思就是

当一个小时内层运行完一次之后,内层Timer释放资源,我想问,外层的

Timer是不是也会释放,还是24小时之中一直都在占用?
我不太清楚你的占用资源是什么意思,如果你在Task中用到一些资源,这些

资源应该在Task运行结束后即刻释放,尤其对竞态条件,更应该占用尽量少

的时间。一般来说,一次Task的运行时间,将少于你设定的周期。否则,

Task将在Timer中堆积起来。如果你要实现上面说的每24小时和每1小时两个

周期的操作,可以使用一个Timer,schedule两个Task即可。

5. Timer是否可以在多线程环境下使用?
可以。Timer中用于存储Task的容器是同步了的,保证了多线程环境先的安全

使用。

6. (austin1979 )请问,定时的时间能为变量,可以在程序中变化吗?就

是说定时的时间可以又界面来控制。
一个Timer可以控制任意多个Task的不同周期设定的触发。也就是说,这个

Timer类似于可以定多个时间的闹钟,比如我的手机就有3个闹钟 :)  。但

是一旦一个Task 已经进行了schedule了,那么就不能再次进行设定。所以,

也不可能再改变其周期、延迟等等设定了。可以看下面的代码:
            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

7. (eqingtian)可不可以认为Timer就是一个线程的发射器?
Timer中仅有一个存储Task的Queue和一个调度所有Task的线程。不管你

schedule几次,在Timer上加了几个Task,都只有一个后台的线程进行调度。
2004年8月13日 9:53

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值