Timer: 一种线程设施,用于安排以后在后台线程中执行的任务。 可安排任务执行一次,或者定期重复执行。
通俗点说就是设定一个时间去执行一次或者重复执行某个任务,例如可以定时提醒用户去激活软件,或者该终止软件的继续使用
TimerTask:由 Timer 安排为一次执行或重复执行的任务。
该类是实现了Runnable接口
列子:
(1)首先创建了一个Timer计时器对象,这里使用了Timer(String name)的构造函数
(2)利用Calendar创建一个开始执行的时间
(3)调用Timer类的schedule方法,执行任务。这里给出的Date time参数如果小于当前时间,则会立即执行。(备注:因为schedule方法有很多重载形式,我这里不一一列出,可自行查看API文档)
(4)重写TimerTask中的Run方法
public class TimerTest { public static void main(String[] args) { /* * 创建Timer对象: 一种线程设施,用于安排以后在后台线程中执行的任务。 可安排任务执行一次,或者定期重复执行。
* */ Timer tm = new Timer("MyThread"); /* * 安排指定的任务 */ Calendar cal = Calendar.getInstance(); cal.set(2015, 1, 1, 13, 40, 00); tm.schedule(new TimerTask() { @Override public void run() {
//输出线程的名称,其值为 MyThread
System.err.println(Thread.currentThread().getName()); while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } /* * 输出每秒时间 */ SimpleDateFormat sdf = new SimpleDateFormat( "YYYY-MM-DD hh:mm:ss"); String time = sdf.format(new Date()); System.err.println(time); } } }, cal.getTime(), 1000); } }
主要是解释一下
(1)要开启守护线程,应先置于true
(2)守护线程的生命周期,当前台线程已经结束时,守护线程也跟随结束,里面的内容也将不会执行
(3)这里的执行结果中,afeter sleep......不会被执行。因为sleep使该线程放弃了CPU的使用权
(4)这里传入的时间参数为new Date(),即表明是立即执行,所以守护线程的名称和Before sleep......会被打印,
如果,传入的参数为1000,也就是1秒钟,那么守护线程的名称和Before sleep......也将不会被打印,因为JVM已经认为没有线程可执行了
public class TimerDaemon_1 { public static void main(String[] args) { //打印主线程名称 System.out.println(Thread.currentThread().getName()+"............"); //默认值为false final Timer tr = new Timer("MyThread", true); tr.schedule(new TimerTask() { @Override public void run() { System.out.println(Thread.currentThread().getName()); System.out.println("Before sleep ............"); try { Thread.sleep(1000);// 这里让该线程休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("After sleep.............."); }//这里的new Date()表示了立即执行 }, new Date()); } }