定时器基本介绍

文章介绍了Java中的定时器Timer的使用,包括schedule方法的四个重载形式,用于在指定延迟后执行或周期性执行任务。此外,文章还详细讲解了如何自定义一个定时器,通过实现Runnable接口的任务类和使用优先级队列来管理并按时间顺序执行任务。
摘要由CSDN通过智能技术生成

目录

目录

一.定时器的使用

1.schedule方法

2.四个重载方法

二.实现一个定时器


定时器是软件开发的一个重要组件,当到达规定的时刻后,执行某个特定的任务。

一.定时器的使用

1.schedule方法

java标准库实现了定时器类 --- Timer。如下代码:

public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask(){
            @Override
            public void run() {
                System.out.println(1);
            }
        },3000);
    }

此代码的结果是:安排了一个任务,在程序开始执行的三秒后,打印 1

Timer类核心的方法就是schedule(),作用是给定时器安排什么任务,以及执行的时间,此方法包含了两个参数,第一个参数TimerTask继承了Runnable接口,可以认为TimerTask就代表了一个任务清单,第二和参数则是指定的时间。

2.四个重载方法

schedule重载了四个方法:

  1. public void schedule(TimerTask task, long delay)         
    delay单位为毫秒,执行到此处代码的delay毫秒后,执行任务。 
  2. public void schedule(TimerTask task, Date time)
    当时间达到time时,执行任务。
  3. public void schedule(TimerTask task, long delay, long period) 
    执行到此处代码的delay毫秒后,第一个执行任务,此后每过period毫秒的时间间隔执行一次。
  4. public void schedule(TimerTask task, Date firstTime, long period)
    时间达到firstTime时,执行任务,此后每过period毫秒的时间间隔执行一次。
    


二.实现一个定时器

        如果要实现一个定时器,我们必须要实现一个任务类,此类实现Runnable接口,然后还必须要有一个数据结构来存放这些任务,那么这里就可以用优先级队列来实现,并按时间来排序,这样队首元素则是时间最接近的任务。

        这里还有一个非常重要的问题,我们必须额外创建一个线程,因为定时器是会自动在到达某一时间时,执行规定任务的,这就要有一个扫描线程不断的检查是否到时间,只要队首的任务到执行时间,就执行任务。

        那么大致框架已明确,代码如下:

class MyTask implements Comparable<MyTask>{
    private long time;

    private Runnable runnable;
    public MyTask(){
    }
    public MyTask(Runnable runnable,long time){
        this.time = time;
        this.runnable = runnable;
    }

    public void run(){
        runnable.run();
    }

    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(MyTask o) {
        return (int)(this.time - o.time);
    }
}
class MyTimer{
    private Thread t = null;

    //使用优先级的阻塞队列来存放任务。
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();

    public MyTimer() throws InterruptedException {
        t = new Thread(()->{
           while(true){
               try {
                   synchronized (this){//1.由于存在notify了但是还没wait的情况,要加锁
                       MyTask task = queue.take();
                       long time = task.getTime();
                       if(time > System.currentTimeMillis()){
                           queue.put(task);
                           this.wait(time - System.currentTimeMillis());
                       }else{
                           task.run();
                       }
                   }
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        t.start();
    }

    //安排任务,
    public void schedule(Runnable runnable, long time){
        MyTask readingTask = new MyTask(runnable,System.currentTimeMillis()+time);
        queue.put(readingTask);
        synchronized (this){//当有新任务加入,就唤醒扫描线程。
            this.notify();
        }
    }
}

 

以上就是本文的全部内容了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

todd1er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值