ExecutorService取代Java Timer

37 篇文章 0 订阅

Java并发编程实战》一书提到的用ExecutorService取代Java Timer有几个理由,我认为其中最重要的理由是: 
如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以 TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。 

stackoverflow上也有关于此问题的讨论: 
http://stackoverflow.com/questions/409932/java-timer-vs-executorservice 

Timer的问题: 

Java代码  

package com.ljn.timer;  

  

import java.util.Date;  

import java.util.Timer;  

  

/** 

 * @author lijinnan 

 * @date:2013-11-25 下午3:27:43   

 */  

10 public class TimerException {  

11   

12     public static void main(String[] args) {  

13         System.out.println("start:" + new Date());  

14         Timer timer = new Timer();  

15         int delay = 1000;  

16         int period = 2000;  

17         timer.schedule(new OKTask(), delay * 2, period);    //"OKTask" does not get chance to execute  

18         timer.schedule(new ErrorTask(), delay, period);  //exception in "ErrorTask" will terminate the Timer  

19     }  

20       

21     /*输出: 

22 start:Mon Nov 25 17:49:53 CST 2013 

23 ErrorTask is executing... 

24 error:Mon Nov 25 17:49:55 CST 2013 

25 Exception in thread "Timer-0" java.lang.RuntimeException: something wrong 

26     at com.ljn.timer.ErrorTask.run(ErrorTask.java:14) 

27      */  

28   

29  }  



ExecutorService则正常: 

Java代码  

30 package com.ljn.timer;  

31   

32 import java.util.Date;  

33 import java.util.concurrent.Executors;  

34 import java.util.concurrent.ScheduledExecutorService;  

35 import java.util.concurrent.TimeUnit;  

36   

37 /** 

38  * @author lijinnan 

39  * @date:2013-11-25 下午3:35:39   

40  */  

41 public class ScheduledExecutorServiceTest {  

42   

43     public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);    

44   

45     public static void main(String[] args){  

46         System.out.println("start:" + new Date());  

47         ErrorTask errorTask = new ErrorTask();  

48         OKTask okTask = new OKTask();  

49         int delay = 1000;  

50         int period = 2000;  

51         scheduledExecutorService.scheduleAtFixedRate(errorTask, delay, period, TimeUnit.MILLISECONDS);   //"ErrorTask" throws Exception and then stopes.  

52         scheduledExecutorService.scheduleAtFixedRate(okTask, delay * 2, period, TimeUnit.MILLISECONDS);     //"OKTask" is executed periodically, not affected by "ErrorTask"  

53           

54         //scheduledExecutorService.shutdown();  

55     }  

56   

57     /* 

58 start:Mon Nov 25 17:54:22 CST 2013 

59 ErrorTask is executing... 

60 error occurs:Mon Nov 25 17:54:24 CST 2013 

61 OKTask is executed:Mon Nov 25 17:54:24 CST 2013 

62 OKTask is executed:Mon Nov 25 17:54:26 CST 2013 

63 OKTask is executed:Mon Nov 25 17:54:28 CST 2013 

64 ...... 

65      */  

66   

67 }  



另外开发中常常会让任务在每天的指定时间点运行,示例如下: 

Java代码  

68 package com.ljn.timer;  

69   

70 import java.util.Date;  

71 import java.util.concurrent.Executors;  

72 import java.util.concurrent.ScheduledExecutorService;  

73 import java.util.concurrent.TimeUnit;  

74   

75 /** 

76  * @author lijinnan 

77  * @date:2013-11-25 下午5:18:55   

78  */  

79 public class FixedDatetimeTaskTest {  

80   

81     public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);    

82   

83     public static void main(String[] args) throws Exception {  

84         System.out.println("start:" + new Date());  

85           

86         //每天的02:30:00执行任务  

87         long delay = Helper.calcDelay(2300);  

88         long period = Helper.ONE_DAY;  

89         scheduledExecutorService.scheduleAtFixedRate(new OKTask(), delay, period, TimeUnit.MILLISECONDS);   

90     }  

91   

92 }  



文章中用到的其他类: 

Java代码  

93 package com.ljn.timer;  

94   

95 import java.util.Date;  

96 import java.util.TimerTask;  

97   

98 public class ErrorTask extends TimerTask {  

99   

100      @Override  

101      public void run() {  

102          try {  

103              System.out.println("ErrorTask is executing...");  

104              Thread.sleep(1000);  

105              System.out.println("error occurs:" + new Date());  

106              throw new RuntimeException("something wrong");  

107          } catch (InterruptedException e) {  

108          }  

109      }  

110        

111  }  

 

Java代码  

112 package com.ljn.timer;  

113   

114 import java.util.Date;  

115 import java.util.TimerTask;  

116   

117    

118 public  class OKTask extends TimerTask {  

119        

120      @Override  

121      public void run() {  

122          System.out.println("OKTask is executed:" + new Date());  

123      }  

124 }  

 

Java代码  

125 package com.ljn.timer;  

126   

127 import org.joda.time.DateTime;  

128   

129 /** 

130  * @author lijinnan 

131  * @date:2013-11-25 下午5:17:40   

132  */  

133 public class Helper {  

134   

135     private Helper() {}  

136       

137     public static final long ONE_DAY = 60 * 60 * 24;  

138       

139     public static long calcDelay(int hour, int minute, int second) {  

140         if (!(0 <= hour && hour <=23 && 0 <= minute && minute <=59 && 0 <=second && second <= 59)) {  

141             throw new IllegalArgumentException();  

142         }  

143         return calcDelay(fixed(hour, minute, second));  

144     }  

145       

146     private static long calcDelay(DateTime targetDatetimeOfToday) {  

147         long delay = 0;  

148         DateTime now = new DateTime();  

149           

150         //时间点已过,只好延时到明天的这个时间点再执行  

151         if (now.isAfter(targetDatetimeOfToday)) {  

152             delay = now.plusDays(1).getMillis() - now.getMillis();  

153               

154         //时间点未到  

155         } else {  

156             delay = targetDatetimeOfToday.getMillis() - now.getMillis();  

157         }  

158           

159         return delay;  

160     }  

161       

162     /** 

163      * 返回这样一个DateTime对象: 

164      * 1.日期为今天 

165      * 2.时分秒为参数指定的值 

166      * @param hour 0-23 

167      * @param minute 0-59 

168      * @param second 0-59 

169      * @return 

170      */  

171     private static DateTime fixed(int hour, int minute, int second) {  

172           

173         return new DateTime()  

174                     .withHourOfDay(hour).withMinuteOfHour(minute).withSecondOfMinute(second);  

175     }  

176   

177 }  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值