Java 计时器

1.Timer and TimerTask:

Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。

TimerTask是一个实现了Runnable接口的抽象类,代表一个可以被Timer执行的任务。

2. Steps :

  (1)继承TimerTask,注意TimerTask是实现Runnable接口的,因此只要重载run() 方法即可。

  (2)创建Timer对象,调用schedule()方法。

3. Methods:

void cancel()

终止此计时器,丢弃所有当前已安排的任务。

int purge()

从此计时器的任务队列中移除所有已取消的任务。

void schedule(TimerTask task, Date time)

安排在指定的时间执行指定的任务。

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

安排指定的任务在指定的时间开始进行重复的固定延迟执行

void schedule(TimerTask task, long delay)

安排在指定延迟后执行指定的任务。

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

安排指定的任务从指定的延迟后开始进行重复的固定延迟执行

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

安排指定的任务在指定的时间开始进行重复的固定速率执行

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

安排指定的任务在指定的延迟后开始进行重复的固定速率执行

注: 时间都是 毫秒 (ms)

schedule VS. scheduleAtFixedRate

这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延,保证调度间隔都是period,而scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。举个栗子:你每个3秒调度一次,那么正常就是0,3,6,9s这样的时间,如果第二次调度花了2s的时间,如果是schedule,就会变成0,3+2,8,11这样的时间,保证间隔,而scheduleAtFixedRate就会变成0,3+2,6,9,压缩间隔,保证调度时间。

4: 如何终止Timer线程

  默认情况下,创建的timer线程会一直执行,主要有下面四种方式来终止timer线程:

  • 调用timer的cancle方法
  • 把timer线程设置成daemon线程,(new Timer(true)创建daemon线程),在jvm里,如果所有用户线程结束,那么守护线程也会被终止,不过这种方法一般不用。
  • 当所有任务执行结束后,删除对应timer对象的引用,线程也会被终止。
  • 调用System.exit方法终止程序。

5. 总结

  • 每一个Timer仅对应唯一一个线程。
  • Timer不保证任务执行的十分精确。
  • Timer类的线程安全的。

Example:

Timer logTimer = new Timer();
        try{
            Set<Property> additionalCompressFields = additionalCompressedLevels.get(timeCompressionLevel);
            Map<String, IPosting> compressedPostings = new HashMap<String, IPosting>();
            final ConcurrentLinkedDeque<Posting> postingsDeque = new ConcurrentLinkedDeque<Posting>();
            postingsDeque.addAll(postings);
            Posting posting = null;
            {
                //Start a timer to print the remaining posting size
                TimerTask task = new TimerTask(){
                    @Override
                    public void run() {
                        if(postingsDeque.size() > 0 ) {
                            LOGGER.log(Level.INFO, ">>>>>> Remainning items to compress [" + postingsDeque.size() + "] <<<<<<<<<");
                        } 
                    }
                    
                };
                logTimer.scheduleAtFixedRate(task, 30000, 30000);
            }
            while((posting = postingsDeque.poll()) != null){
               ...
            }
        }finally{
            logTimer.cancel();
        }

只是个方法一部分,没有运行结果。

原文地址:https://www.cnblogs.com/mid-wk/p/7158952.html