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
可是程序并没有结束
怎么回事呢?看看下面的源码就知道啦
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
}
}
}
那怎么终止这个线程呢?这就要说到Timer类中的cancel()
cancel()
Timer类中的cancel():将任务队列中的全部任务清空
MyTask myTask = new MyTask();
Timer timer = new Timer();
timer.schedule(myTask,new Date(scheduletime));
timer.cancel();
程序结束啦,哈哈哈
当然我们肯定不满足于就执行一次任务,我们想要的是按照我们的时间定时的执行某一任务,这才符合我们的需求。
注意: 有时并不一定会停止计划任务,也即是计划的任务正常执行,原因就是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 重复
规律就是每次任务执行都把最后一个任务放在队列的头