一、三种常用的定时器 
1.Handler类的postDelayed方法:

Handler mHandler = new Handler();
                 Runnable r = new Runnable() {

                    @Override
                    public void run() {
                            //do something
                            //每隔1s循环执行run方法
                            mHandler.postDelayed(this, 1000);
                    }
                };


主线程中调用:  mHandler.postDelayed(r, 100);//延时100毫秒

2.用handler+timer+timeTask方法:

Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                //do something
            }
            super.handleMessage(msg);
        }
    };

    Timer timer = new Timer();
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            Message message = new Message();
            message.what = 1;
            handler.sendMessage(message);
        }
    };
 主线程中调用:timer.schedule(timerTask,1000,500);//延时1s,每隔500毫秒执行一次run方法

3.Thread+handler方法:

Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){
                //do something
            }
            super.handleMessage(msg);

        }
    };

    class MyThread extends Thread {//这里也可用Runnable接口实现
        @Override
        public void run() {
            while (true){
                try {
                    Thread.sleep(1000);//每隔1s执行一次
                    Message msg = new Message();
                    msg.what = 1;
                    handler.sendMessage(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
主线程中调用:new Thread(new MyThread()).start();

二、三种延时的方法: 
1.Handler的postDelayed方法:

new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
              //do something
          }
       }, 1000);    //延时1s执行

2.timer + TimerTask方法:

timer = new Timer();
                 timer.schedule(new TimerTask() {                   
                    @Override
                    public void run() {
                          //do something
                    }
                },1000);//延时1s执行

3.Thread方法:

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);//延时1s
                    //do something
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

三、三种定时器: 

1.Timer + TimerTask方法

String sdate = "2019-01-01";
        SimpleDateFormat sf = new SimpleDateFormat("yy-MM-dd");
        Date date = sf.parse(sdate);

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("系统正在运行……");
            }
        }, date); //在指定的日期运行一次定时任务
    /*如果date日期在今天之前,则启动定时器后,立即运行一次定时任务run方法*/
    /*如果date日期在今天之后,则启动定时器后,会在指定的将来日期运行一次任务run方法*/

2.Timer+TimerTask方法

String sdate = "2018-02-10";
        SimpleDateFormat sf = new SimpleDateFormat("yy-MM-dd");
        Date date = sf.parse(sdate);

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("正在运行……");
            }
        }, date, 2000);
        /*如果指定的date时间是当天或者今天之前,启动定时器后会立即每隔2s运行一次定时器任务*/
        /*如果指定的date时间是未来的某天,启动定时器后会在未来的那天开始,每隔2s执行一次定时器任务*/

四、停止定时器:
停止定时器实质是终止Timer的线程。默认情况下,创建的Timer线程会一直执行,如果要停止的话主要有以下四种方法终止Timer线程:

调用Timer的cancel方法;
把Timer线程设置成Daemon守护线程,当所有的用户线程结束后,那么守护线程也会被终止;
当所有的任务执行结束后,删除对应Timer对象的引用,线程也会被终止;
调用System.exit方法终止程序

1.cancel方法终止Timer线程

/*如果主线程不休眠一段时间,就执行了cancel方法,那么定时器还没来得及执行就会被关闭*/
        Thread.sleep(5000);
        timer.cancel();

五、启动定时器源码:

启动一个定时器实质是启动一个线程,每创建一个定时器,就需要新建一个线程,用新创建的线程去执行定时器任务。 
当执行Timer timer = new Timer(); 时,

执行了Timer的无参构造器

public Timer() {
        this("Timer-" + serialNumber());
    }

Timer的有参构造器.(设置线程的名字,然后启动线程)

public Timer(String name) {
        thread.setName(name);
        thread.start();
    }