schedule(TimerTask task,Date time)

在指定日期执行一次任务

public class MyTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("任务执行了,时间为:"+System.currentTimeMillis());
    }
}
public class TimerDemo {
    public static void main(String[] args) throws InterruptedException {
    
        long nowtime = System.currentTimeMillis();
        System.out.println("当前时间为:"+nowtime);

        long scheduletime = nowtime+1000;
        System.out.println("计划任务时间为:"+scheduletime);

        TimeUnit.SECONDS.sleep(1);

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,new Date(scheduletime));
      
    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=55036:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program 6.0.6.jar;D:\apache-maven-3.5.4-bin\rep\com\alibaba\druid\1.1.20\druid-1.1.20.jar" 
当前时间为:1600341202952
计划任务时间为:1600341203952
任务执行了,时间为:1600341203956

可是程序并没有结束

Look !  Timer定时器_线程
怎么回事呢?看看下面的源码就知道啦

public Timer() {
        this("Timer-" + serialNumber());
    }
 public Timer(String name) {
        thread.setName(name);
        thread.start();
    }
/**
     * The timer thread.
     */
    private final TimerThread thread = new TimerThread(queue);

我们在创建一个timer时,会伴生产生一个新的线程,用新的线程执行任务。

class TimerThread extends Thread {

为什么 TimerThread 线程没有停止呢,原因是存在死循环

public void run() {
        try {
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }

Look !  Timer定时器_线程_02

那怎么终止这个线程呢?这就要说到Timer类中的cancel()

cancel()

Timer类中的cancel():将任务队列中的全部任务清空

MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,new Date(scheduletime));
        timer.cancel();

Look !  Timer定时器_timer_03
程序结束啦,哈哈哈
当然我们肯定不满足于就执行一次任务,我们想要的是按照我们的时间定时的执行某一任务,这才符合我们的需求。

注意: 有时并不一定会停止计划任务,也即是计划的任务正常执行,原因就是cancel可能并没有抢到queen锁。

schedule(TimerTask task,Date time,long period)

schedule(TimerTask task,Date time,long period) :在指定日期之后按照指定的间隔周期无限循环执行任务
long period:指的是指定的时间,单位毫秒

public class TimerDemo {
    public static void main(String[] args) throws InterruptedException {
      
        long nowtime = System.currentTimeMillis();
        System.out.println("当前时间为:"+nowtime);

        long scheduletime = nowtime+1000;
        System.out.println("计划任务时间为:"+scheduletime);

        TimeUnit.SECONDS.sleep(1);

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
    
        timer.schedule(myTask,new Date(scheduletime),2000);


    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=55333:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program 6.0.6.jar;D:\apache-maven-3.5.4-bin\rep\com\alibaba\druid\1.1.20\druid-1.1.20.jar" 
当前时间为:1600342551653
计划任务时间为:1600342552653
任务执行了,时间为:1600342552655
任务执行了,时间为:1600342554656
任务执行了,时间为:1600342556656
任务执行了,时间为:1600342558657
任务执行了,时间为:1600342560658
任务执行了,时间为:1600342562658
。。。。省略。。。。

是不是也可以移除呢 答案是可以的,但是这次不是移除全部任务,而是移除自己本身

public class MyTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("A任务执行了,时间为:"+System.currentTimeMillis());
        this.cancel();
        System.out.println("A把自己移除了");
    }
}
public class MyTaskB extends TimerTask {
    @Override
    public void run() {
        System.out.println("B任务执行了,时间为:"+System.currentTimeMillis());

    }
}
public class TimerDemo {
    public static void main(String[] args) throws InterruptedException {
      
        long nowtime = System.currentTimeMillis();
        System.out.println("当前时间为:"+nowtime);

        long scheduletime = nowtime+1000;
        System.out.println("计划任务时间为:"+scheduletime);

        TimeUnit.SECONDS.sleep(1);

        MyTask myTask = new MyTask();
        MyTaskB myTaskB = new MyTaskB();
        Timer timer = new Timer();
    
        timer.schedule(myTask,new Date(scheduletime),2000);
        timer.schedule(myTaskB,new Date(scheduletime),2000);


    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=55434:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program 6.0.6.jar;D:\apache-maven-3.5.4-bin\rep\com\alibaba\druid\1.1.20\druid-1.1.20.jar" 
当前时间为:1600343035196
计划任务时间为:1600343036196
A任务执行了,时间为:1600343036202
A把自己移除了
B任务执行了,时间为:1600343036202
B任务执行了,时间为:1600343038203
B任务执行了,时间为:1600343040203
B任务执行了,时间为:1600343042204
B任务执行了,时间为:1600343044204
B任务执行了,时间为:1600343046207
。。。。省略。。。。

接下来看看多任务的执行顺序是怎么样的

public class TimerDemo {
    public static void main(String[] args) throws InterruptedException {
      
        long nowtime = System.currentTimeMillis();
        System.out.println("当前时间为:"+nowtime);

        long scheduletime = nowtime+1000;
        System.out.println("计划任务时间为:"+scheduletime);

        TimeUnit.SECONDS.sleep(1);

        MyTaskA myTaskA = new MyTaskA();
        MyTaskB myTaskB = new MyTaskB();
        MyTaskC myTaskC = new MyTaskC();
        Timer timer = new Timer();
  
        timer.schedule(myTaskA,new Date(scheduletime),2000);
        timer.schedule(myTaskB,new Date(scheduletime),2000);
        timer.schedule(myTaskC,new Date(scheduletime),2000);


    }
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=56189:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program 6.0.6.jar;D:\apache-maven-3.5.4-bin\rep\com\alibaba\druid\1.1.20\druid-1.1.20.jar" 
当前时间为:1600344827505
计划任务时间为:1600344828505
A任务执行了,时间为:1600344828509
B任务执行了,时间为:1600344828509
C任务执行了,时间为:1600344828509
C任务执行了,时间为:1600344830519
A任务执行了,时间为:1600344830519
B任务执行了,时间为:1600344830519
B任务执行了,时间为:1600344832519
C任务执行了,时间为:1600344832519
A任务执行了,时间为:1600344832519
A任务执行了,时间为:1600344834519
B任务执行了,时间为:1600344834519
C任务执行了,时间为:1600344834519
C任务执行了,时间为:1600344836520
A任务执行了,时间为:1600344836520
B任务执行了,时间为:1600344836520
B任务执行了,时间为:1600344838521
C任务执行了,时间为:1600344838521
A任务执行了,时间为:1600344838521
A任务执行了,时间为:1600344840522
B任务执行了,时间为:1600344840522
C任务执行了,时间为:1600344840522
C任务执行了,时间为:1600344842522
A任务执行了,时间为:1600344842522
B任务执行了,时间为:1600344842522

Process finished with exit code -1

发现是ABC–>CAB–>BCA 重复
规律就是每次任务执行都把最后一个任务放在队列的头