Java Timer的使用,守护线程。

本文介绍 Java Timer 的多种应用场景,包括但不限于定期任务调度、守护线程的实现及任务取消等。通过示例代码详细展示了如何利用 Timer 和 TimerTask 类实现定时功能。
  1. package cn.vicky;  
  2.   
  3. import java.util.Timer;  
  4.   
  5. /** 
  6.  * Timer : 提供对计时器 MBean 的实现。 计时器 MBean 将在指定的时间发出警告,以唤醒所有注册的侦听器来接收计时器通知。 此类管理一个过期的计时器通知列表。 
  7.  * 这是一种允许用户根据需要任意添加/移除通知的方法。 当计时器发出计时器通知并过时后,会将该通知自动从计时器通知列表中移除。 可以将其他计时器通知添加到常规重复发送的通知中。 
  8.  */  
  9. public class MyTimer {  
  10.   
  11.     public static void main(String[] args) {  
  12.         Timer timer = new Timer();  
  13.         // 在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.   
  14.         timer.schedule(new MyTask(), 10002000);  
  15.         // 这个是用来停止此任务的,否则就一直循环执行此任务了   
  16.         try {  
  17.             Thread.sleep(10000);  
  18.         } catch (InterruptedException e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.         // 使用这个方法退出任务   
  22.         timer.cancel();  
  23.     }  
  24.   
  25.     static class MyTask extends java.util.TimerTask {  
  26.         @Override  
  27.         public void run() {  
  28.             System.out.println("Done !");  
  29.         }  
  30.     }  
  31. }  
[java]  view plain  copy
  1. package cn.vicky;  
  2.   
  3. import java.util.Timer;  
  4.   
  5. /** 
  6.  * Timer : 提供对计时器 MBean 的实现。 计时器 MBean 将在指定的时间发出警告,以唤醒所有注册的侦听器来接收计时器通知。 此类管理一个过期的计时器通知列表。 
  7.  * 这是一种允许用户根据需要任意添加/移除通知的方法。 当计时器发出计时器通知并过时后,会将该通知自动从计时器通知列表中移除。 可以将其他计时器通知添加到常规重复发送的通知中。 
  8.  */  
  9. public class MyTimer {  
  10.   
  11.     public static void main(String[] args) {  
  12.         Timer timer = new Timer();  
  13.         // 在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.  
  14.         timer.schedule(new MyTask(), 10002000);  
  15.         // 这个是用来停止此任务的,否则就一直循环执行此任务了  
  16.         try {  
  17.             Thread.sleep(10000);  
  18.         } catch (InterruptedException e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.         // 使用这个方法退出任务  
  22.         timer.cancel();  
  23.     }  
  24.   
  25.     static class MyTask extends java.util.TimerTask {  
  26.         @Override  
  27.         public void run() {  
  28.             System.out.println("Done !");  
  29.         }  
  30.     }  
  31. }  

Done !
Done !
Done !
Done !
……

 

 

守护线程的实现。这是我对Timer比较满意的功能,很好,很强大^_^!

  1. package cn.vicky;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. public class MyTimer2 {  
  7.   
  8.     private String name;  
  9.     private long timeOut;  
  10.   
  11.     private Thread thread;  
  12.   
  13.     public MyTimer2(String name, long timeOut) {  
  14.         this.name = name;  
  15.         this.timeOut = timeOut;  
  16.     }  
  17.   
  18.     /** 
  19.      * 在节点的处理线程消耗的时间过长时,计时器将调用{@link System#exit System.exit} 系统退出的方法,强制该节点的事务处理线程关闭。这个计时器是一个守护进程, 
  20.      * 所以当一个服务正常完整的关闭时,任务不会运行该程序。 
  21.      */  
  22.     public void startShutdownTimeout(long timeOut) {  
  23.         new Timer(true).schedule(new TimerTask() { // true,表示执行的线程是一个守护线程   
  24.                     @Override  
  25.                     public void run() {  
  26.                         System.out.println("线程" + name + "超时,执行守护线程 !");  
  27.                         // System.exit(1);   
  28.                         thread.stop();  
  29.                     }  
  30.                 }, timeOut);  
  31.     }  
  32.   
  33.     public void myTest() {  
  34.         thread = new Thread(){  
  35.             @Override  
  36.             public void run() {  
  37.                 startShutdownTimeout(timeOut); // 该线程受到守护线程的作用   
  38.                 System.out.println(name + "Begin");  
  39.                 try {  
  40.                     Thread.sleep(200); // 函数要执行至少200毫秒   
  41.                 } catch (InterruptedException e) {  
  42.                     e.printStackTrace();  
  43.                 }  
  44.                 System.out.println(name + "Over");  
  45.             }  
  46.         };  
  47.         thread.start();  
  48.     }  
  49.   
  50.     public static void main(String[] args) {  
  51.         MyTimer2 m1 = new MyTimer2("1 - "100);  
  52.         MyTimer2 m2 = new MyTimer2("2 - "180);  
  53.         MyTimer2 m3 = new MyTimer2("3 - "250);  
  54.         MyTimer2 m4 = new MyTimer2("4 - "320);  
  55.           
  56.         m1.myTest();  
  57.         m2.myTest();  
  58.         m3.myTest();  
  59.         m4.myTest();  
  60.     }  
  61. }  
[java]  view plain  copy
  1. package cn.vicky;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. public class MyTimer2 {  
  7.   
  8.     private String name;  
  9.     private long timeOut;  
  10.   
  11.     private Thread thread;  
  12.   
  13.     public MyTimer2(String name, long timeOut) {  
  14.         this.name = name;  
  15.         this.timeOut = timeOut;  
  16.     }  
  17.   
  18.     /** 
  19.      * 在节点的处理线程消耗的时间过长时,计时器将调用{@link System#exit System.exit} 系统退出的方法,强制该节点的事务处理线程关闭。这个计时器是一个守护进程, 
  20.      * 所以当一个服务正常完整的关闭时,任务不会运行该程序。 
  21.      */  
  22.     public void startShutdownTimeout(long timeOut) {  
  23.         new Timer(true).schedule(new TimerTask() { // true,表示执行的线程是一个守护线程  
  24.                     @Override  
  25.                     public void run() {  
  26.                         System.out.println("线程" + name + "超时,执行守护线程 !");  
  27.                         // System.exit(1);  
  28.                         thread.stop();  
  29.                     }  
  30.                 }, timeOut);  
  31.     }  
  32.   
  33.     public void myTest() {  
  34.         thread = new Thread(){  
  35.             @Override  
  36.             public void run() {  
  37.                 startShutdownTimeout(timeOut); // 该线程受到守护线程的作用  
  38.                 System.out.println(name + "Begin");  
  39.                 try {  
  40.                     Thread.sleep(200); // 函数要执行至少200毫秒  
  41.                 } catch (InterruptedException e) {  
  42.                     e.printStackTrace();  
  43.                 }  
  44.                 System.out.println(name + "Over");  
  45.             }  
  46.         };  
  47.         thread.start();  
  48.     }  
  49.   
  50.     public static void main(String[] args) {  
  51.         MyTimer2 m1 = new MyTimer2("1 - "100);  
  52.         MyTimer2 m2 = new MyTimer2("2 - "180);  
  53.         MyTimer2 m3 = new MyTimer2("3 - "250);  
  54.         MyTimer2 m4 = new MyTimer2("4 - "320);  
  55.           
  56.         m1.myTest();  
  57.         m2.myTest();  
  58.         m3.myTest();  
  59.         m4.myTest();  
  60.     }  
  61. }  

2 - Begin
3 - Begin
4 - Begin
1 - Begin
线程1 - 超时,执行守护线程 !
线程2 - 超时,执行守护线程 !
3 - Over
4 - Over

 

  1. package cn.vicky;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Timer;  
  5.   
  6. /* 
  7.  * 本类给出了使用Timer和TimerTaske的主要方法,其中包括定制任务,添加任务退出任务,退出定时器. 
  8.  * 因为TimerTask的status域是包级可访问的,所以没有办法在java.util.包外得到其状态,这对编程造成一些不便. 
  9.  * 我们不能判断某个Task的状态了. 
  10.  */  
  11. public class MyTimer3 {  
  12.   
  13.     public static void main(String[] args) {  
  14.         Timer timer = new Timer();  
  15.         MyTask myTask1 = new MyTask();  
  16.         MyTask myTask2 = new MyTask();  
  17.         myTask2.setInfo("myTask-2");  
  18.         timer.schedule(myTask1, 10005000);  
  19.         timer.scheduleAtFixedRate(myTask2, 20005000);  
  20.         while (true) {  
  21.             try {  
  22.                 byte[] info = new byte[1024];  
  23.                 int len = System.in.read(info);  
  24.                 String strInfo = new String(info, 0, len, "GBK");// 从控制台读出信息   
  25.                 if (strInfo.charAt(strInfo.length() - 1) == ' ') {  
  26.                     strInfo = strInfo.substring(0, strInfo.length() - 2);  
  27.                 }  
  28.                 if (strInfo.startsWith("Cancel-1")) {  
  29.                     // 退出单个任务   
  30.                     myTask1.cancel();  
  31.                     // 其实应该在这里判断myTask2是否也退出了,是的话就应该break.但是因为无法在包外得到  
  32.                     // myTask2的状态,所以,这里不能做出是否退出循环的判断.   
  33.                 } else if (strInfo.startsWith("Cancel-2")) {  
  34.                     myTask2.cancel();  
  35.                 } else if (strInfo.startsWith("Cancel-All")) {  
  36.                     // 退出Timer   
  37.                     timer.cancel();  
  38.                     break;  
  39.                 } else {  
  40.                     // 只对myTask1作出判断,偷个懒^_^   
  41.                     myTask1.setInfo(strInfo);  
  42.                 }  
  43.             } catch (IOException e) {  
  44.                 e.printStackTrace();  
  45.             }  
  46.         }  
  47.     }  
  48.   
  49.     static class MyTask extends java.util.TimerTask {  
  50.         String info = "^_^";  
  51.   
  52.         @Override  
  53.         public void run() {  
  54.             System.out.println(info);  
  55.         }  
  56.   
  57.         public String getInfo() {  
  58.             return info;  
  59.         }  
  60.   
  61.         public void setInfo(String info) {  
  62.             this.info = info;  
  63.         }  
  64.   
  65.     }  
  66.   
  67. }  
[java]  view plain  copy
  1. package cn.vicky;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Timer;  
  5.   
  6. /* 
  7.  * 本类给出了使用Timer和TimerTaske的主要方法,其中包括定制任务,添加任务退出任务,退出定时器. 
  8.  * 因为TimerTask的status域是包级可访问的,所以没有办法在java.util.包外得到其状态,这对编程造成一些不便. 
  9.  * 我们不能判断某个Task的状态了. 
  10.  */  
  11. public class MyTimer3 {  
  12.   
  13.     public static void main(String[] args) {  
  14.         Timer timer = new Timer();  
  15.         MyTask myTask1 = new MyTask();  
  16.         MyTask myTask2 = new MyTask();  
  17.         myTask2.setInfo("myTask-2");  
  18.         timer.schedule(myTask1, 10005000);  
  19.         timer.scheduleAtFixedRate(myTask2, 20005000);  
  20.         while (true) {  
  21.             try {  
  22.                 byte[] info = new byte[1024];  
  23.                 int len = System.in.read(info);  
  24.                 String strInfo = new String(info, 0, len, "GBK");// 从控制台读出信息  
  25.                 if (strInfo.charAt(strInfo.length() - 1) == ' ') {  
  26.                     strInfo = strInfo.substring(0, strInfo.length() - 2);  
  27.                 }  
  28.                 if (strInfo.startsWith("Cancel-1")) {  
  29.                     // 退出单个任务  
  30.                     myTask1.cancel();  
  31.                     // 其实应该在这里判断myTask2是否也退出了,是的话就应该break.但是因为无法在包外得到  
  32.                     // myTask2的状态,所以,这里不能做出是否退出循环的判断.  
  33.                 } else if (strInfo.startsWith("Cancel-2")) {  
  34.                     myTask2.cancel();  
  35.                 } else if (strInfo.startsWith("Cancel-All")) {  
  36.                     // 退出Timer  
  37.                     timer.cancel();  
  38.                     break;  
  39.                 } else {  
  40.                     // 只对myTask1作出判断,偷个懒^_^  
  41.                     myTask1.setInfo(strInfo);  
  42.                 }  
  43.             } catch (IOException e) {  
  44.                 e.printStackTrace();  
  45.             }  
  46.         }  
  47.     }  
  48.   
  49.     static class MyTask extends java.util.TimerTask {  
  50.         String info = "^_^";  
  51.   
  52.         @Override  
  53.         public void run() {  
  54.             System.out.println(info);  
  55.         }  
  56.   
  57.         public String getInfo() {  
  58.             return info;  
  59.         }  
  60.   
  61.         public void setInfo(String info) {  
  62.             this.info = info;  
  63.         }  
  64.   
  65.     }  
  66.   
  67. }  

^_^
myTask-2
^_^
myTask-2
OY  //  输入的内容,将替换原有的
OY

myTask-2
OY

myTask-2
OY

Java 的 `Timer` 类是用于计划任务的工具类,可在后台线程中定时执行任务或延迟执行任务,常配合 `TimerTask` 使用,适合在指定时间执行一次任务或周期性地执行任务的场景。以下是具体使用方法: ### 定义任务 用户需要继承 `TimerTask` 类并重写其 `run()` 方法来定义任务的具体内容。示例代码如下: ```java import java.text.DateFormat; import java.util.Date; // 自定义 TimeUtil 类模拟获取日期格式 class TimeUtil { static ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return null; // 这里应根据实际情况返回合适的 DateFormat 实例 } }; } public class MyTask extends java.util.TimerTask { @Override public void run() { DateFormat dateFormat = TimeUtil.df.get(); System.out.println("我的任务运行了" + dateFormat.format(new Date())); } } ``` ### 执行任务 可以使用 `Timer` 类的 `schedule` 方法来安排任务的执行。以下是几种常见的使用方式: #### 在指定时间执行任务 ```java import java.text.ParseException; import java.util.Timer; public class Run { private static Timer timer = new Timer(); public static void main(String[] args) throws ParseException { timer.schedule(new MyTask(), TimeUtil.df.get().parse("2017-09-14 09:19:30")); } } ``` #### 延迟一段时间后执行任务 ```java import java.util.Timer; import java.util.TimerTask; public class Test { public static void main(String[] args) { Timer timer = new Timer(); // 延迟 1000 毫秒后执行任务 timer.schedule(new MyTask(), 1000); } } ``` #### 延迟一段时间后周期性执行任务 ```java import java.util.Timer; import java.util.TimerTask; public class Test { public static void main(String[] args) { // 参数为 true 代表该线程为后台线程,如果是 false 则代表非后台线程 Timer timer = new Timer(true); // 延迟 1000 毫秒后开始执行任务,之后每隔 2000 毫秒执行一次 timer.schedule(new MyTask(), 1000, 2000); } } class MyTask extends TimerTask { @Override public void run() { System.out.println("hello"); } } ``` ### 创建守护线程的定时器 如果想要 `Timer` 内部创建的是守护线程,可以使用以下构造方法创建定时器,设置 `isDaemon` 为 `true`: ```java import java.util.Timer; public class DaemonTimerExample { public static void main(String[] args) { // 创建一个守护线程的定时器 Timer timer = new Timer(true); // 安排任务 timer.schedule(new MyTask(), 1000); } } ``` ### 注意事项 - `Timer` 类在内部使用多线程的方式进行处理,和多线程技术有较大关联。 - `Timer` 类主要负责计划任务的功能,封装任务的类是 `TimerTask` 类 [^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值