5.定时器Timer
来源:互联网 发布:It 门槛 编辑:程序博客网 时间:2024/06/16 14:27
本章着重掌握如下2个知识点:
- 如何实现指定时间执行任务
- 如何实现按指定周期执行任务
定时器Timer的使用
介绍:在JDK库中Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。Timer类的主要作用就设置计划任务,但封装任务的类却是TimerTask类。执行任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类。
方法schedule(TimerTask task, Date time):
说明:该方法的作用是在指定的日期执行一次某一任务
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); static public class MyTask extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args){ try{ MyTask task = new MyTask(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 17:48:00"; Date dateRef = sdf.parse(dateString); System.out.println("字符串时间: " + dateRef.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); timer.schedule(task, dateRef); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
分析:1.从结果可以看到,任务虽然执行完了,但进程还未销毁,呈红色状态,为什么会出现这样的情况呢?查看Timer的构造方法可以得知,创建一个Timer就是启动了一个新的线程,这个新启动的线程并不是守护线程,它一直在运行。如果想让Timer成为守护线程,该怎么做呢?new Timer(true)就可以了。2.根据所提供的datetime,如果大于当前时间,则到响应时间执行,若小于等于当前时间,则任务立即执行。
多个TimerTask任务
**介绍:**Timer中允许有多个TimerTask任务。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); static public class MyTask1 extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } static public class MyTask2 extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args){ try{ MyTask1 task1 = new MyTask1(); MyTask2 task2 = new MyTask2(); SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString1 = "2017-04-28 18:50:00"; String dateString2 = "2017-04-28 17:51:00"; Date dateRef1 = sdf1.parse(dateString1); Date dateRef2 = sdf1.parse(dateString2); System.out.println("字符串1时间: " + dateRef1.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); System.out.println("字符串2时间: " + dateRef2.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); timer.schedule(task1, dateRef1); timer.schedule(task2, dateRef2); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
总结:TimerTask是以队列的方式一个一个被顺序执行的,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间较长,则后面的任务运行的时间也会被延迟。
方法shcedule(TimerTask task, Date firstTime, long period)
说明:该方法的作用是指在指定的日期后,按指定的间隔周期性地无限循环地执行某一任务。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); static public class MyTask extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args){ try{ MyTask task = new MyTask(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 18:57:00"; Date dateRef = sdf.parse(dateString); System.out.println("字符串1时间: " + dateRef.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); timer.schedule(task, dateRef, 4000); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
总结:从运行结果来看,每隔4秒运行一次TimerTask任务,并且是无限期地重复执行。
TimerTask类的cancel()方法
**说明:**TimerTask类中的cancel()方法的作用是将自身从任务队列中清除。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); static public class MyTaskA extends TimerTask{ @Override public void run(){ System.out.println("A运行了!时间为:" + new Date()); this.cancel(); } } static public class MyTaskB extends TimerTask{ @Override public void run(){ System.out.println("B运行了!时间为:" + new Date()); } } public static void main(String[] args){ try{ MyTaskA taskA = new MyTaskA(); MyTaskB taskB = new MyTaskB(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 18:57:00"; Date dateRef = sdf.parse(dateString); System.out.println("字符串时间: " + dateRef.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); timer.schedule(taskA, dateRef, 4000); timer.schedule(taskB, dateRef, 4000); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
总结:从运行结果来看,TimerTask类的cancel()方法是将自身从任务队列中被移除,其他任务不受影响。
Timer类的cancel()方法
说明:和TimerTask类中的cancel()方法清除自身不同,Timer类中的cancel()方法的作用是将任务队列中的全部任务清空。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); static public class MyTaskA extends TimerTask{ @Override public void run(){ System.out.println("A运行了!时间为:" + new Date()); timer.cancel(); } } static public class MyTaskB extends TimerTask{ @Override public void run(){ System.out.println("B运行了!时间为:" + new Date()); } } public static void main(String[] args){ try{ MyTaskA taskA = new MyTaskA(); MyTaskB taskB = new MyTaskB(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 18:57:00"; Date dateRef = sdf.parse(dateString); System.out.println("字符串时间: " + dateRef.toLocaleString() + " 当前时间: " + new Date().toLocaleString()); timer.schedule(taskA, dateRef, 4000); timer.schedule(taskB, dateRef, 4000); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
总结:从运行结果来看,全部任务都被清除,并且进程被销毁,按钮又红色变成灰色。
Timer类的cancel()方法的注意事项
**说明:**Timer类中的cancel()方法有时并不一定会停止执行计划任务,而是正常执行。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Created by yongshan_ning on 2017/4/28. */public class Run1 { static int i = 0; static public class MyTask extends TimerTask{ @Override public void run(){ System.out.println("A运行了!时间为:" + i); } } public static void main(String[] args){ while (true) { try { i++; Timer timer = new Timer(); MyTask task = new MyTask(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 18:57:00"; Date dateRef = sdf.parse(dateString); timer.schedule(task, dateRef); timer.cancel(); } catch (ParseException e) { e.printStackTrace(); } } }}
结果:
总结:因为Timer类中的cancel()方法有时并没有争抢到queue锁,所以TimerTask类中的任务继续正常执行了。
方法schedule(TimerTask task, long delay)
说明:该方法的作用是以执行shcedule(TimerTask task, long delay)方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务。
看个例子:
import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { static public class MyTask extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args) { Timer timer = new Timer(); MyTask task = new MyTask(); System.out.println("当前时间: " + new Date().toLocaleString()); timer.schedule(task, 7000); }}
结果:
总结:从运行结果来看,任务task被延迟7秒执行。
方法schedule(TimerTask task, long delay, long period)
说明:该方法的作用是以执行shcedule(TimerTask task, long delay, long period)方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数,再以某一件间隔无限次数地执行某一任务。
看个例子:
import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { static public class MyTask extends TimerTask{ @Override public void run(){ System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args) { Timer timer = new Timer(); MyTask task = new MyTask(); System.out.println("当前时间: " + new Date().toLocaleString()); timer.schedule(task, 3000, 5000); }}
结果:
总结:从运行结果来看,任务task被延迟3秒执行,并间隔5秒无限循环执行。
方法scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
说明:方法schedule和方法scheduleAtFixedRate都会按顺序执行,所以不要考虑非线程安全的情况。方法shcedule和scheduleAtFixedRate主要的区别只在于不延时的情况。
使用schedule方法:如果执行任务的时间没有被延时,那么下一次任务的执行事件参考的是上一次任务的”开始”时的时间来计算。
使用scheduleAtFixedRate方法:如果执行任务的时间没有被延时,那么下一次任务的执行事件参考的是上一次任务的”结束”时的时间来计算。
延时的情况则没有区别,也就是使用shcedule或scheduleAtFixedRate方法都是如果执行任务的时间被延时,那么下一次任务的执行事件参考的是上一次任务”结束”时的时间来计算。
看个例子:
import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Run1 { private static Timer timer = new Timer(); private static int runCount = 0; static public class MyTask extends TimerTask{ @Override public void run(){ try { System.out.println("begin 运行了!时间为:" + new Date()); Thread.sleep(1000); System.out.println(" end 运行了!时间为:" + new Date()); runCount++; if(runCount == 5){ timer.cancel(); } }catch (InterruptedException e){ e.printStackTrace(); } } } public static void main(String[] args) { try { MyTask task = new MyTask(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = "2017-04-28 19:39:00"; Date dateRef = sdf.parse(dateString); System.out.println("字符串时间"+dateRef.toLocaleString()+" 当前时间: " + new Date().toLocaleString()); timer.scheduleAtFixedRate(task, dateRef, 3000); }catch (ParseException e){ e.printStackTrace(); } }}
结果:
总结:从运行结果来看,如果执行任务的时间没有被延时,则下一次任务的执行事件以上一次任务的开始时间加上delay时间。反之,如果被延时,则下一次执行任务的时间是上一次任务结束的时间。schedule方法不具有追赶执行性,scheduleAtFixedRate方法具有追赶执行性。
- 5.定时器Timer
- Timer 定时器
- TIMER 定时器
- timer 定时器
- timer 定时器
- timer定时器
- 定时器 Timer
- 定时器Timer
- timer定时器
- Timer 定时器
- Timer定时器
- 定时器TIMER
- 定时器Timer
- timer定时器
- Timer 定时器
- Timer定时器
- 定时器 timer
- 定时器 Timer
- CPU卡程序设计实例(二十一)4字节随机数读取
- ===============个人博客导航栏======================
- 抽象与计算机课程
- 显卡驱动
- C++异常处理机制
- 5.定时器Timer
- hdu5691_Sitting in Line_状压dp
- [SSRS / RV](.rdlc报表)Reporting Services多印空白页的解決方式
- Promise浅析(一)——基础篇
- 博客开始时间
- NYOJ 整数划分
- RANSAC算法总结
- 前端 mac 上编程软件 编程软件
- 极大似然估计