使用ScheduledThreadPoolExecutor代替Timer&TimerTask
- - ITeye博客 如果我们想要延迟(deferred)或者周期性(periodic)执行一个任务,我们可以使用Java API 的Timer和TimerTask类. 一般步骤是:. 继承TimerTask(抽象类),复写run方法,方法体里代表需要执行的任务.
如果我们想要延迟(deferred)或者周期性(periodic)执行一个任务,我们可以使用Java API 的Timer和TimerTask类。
一般步骤是:
继承TimerTask(抽象类),复写run方法,方法体里代表需要执行的任务。
实例化Timer(可以通过构造方法设置为守护线程),调用schedule的一个重载方法实现延迟或者周期性执行自定义任务。
下面的例子演示了程序启动5秒后每隔1秒警报器叫一声,10次后终止程序执行。
import java.awt.Toolkit; import java.util.Timer; import java.util.TimerTask; /** * 自定义Timer类 * */ class BeepTimer extends TimerTask { private Toolkit toolKit; private int count; public BeepTimer() { toolKit = Toolkit.getDefaultToolkit(); } @Override public void run() { if (count == 10) System.exit(1); toolKit.beep(); count++; } } public class TimerDemo { public static void main(String... args) { BeepTimer bt = new BeepTimer(); //非守护线程 Timer timer = new Timer(); timer.schedule(bt, 5 * 1000, 1 * 1000); // 5秒后开始鸣叫,鸣叫10次,每次相隔1秒钟 } }
但是Timer和TimerTask存在一些缺陷:
1:Timer只创建了一个线程。当你的任务执行的时间超过设置的延时时间将会产生一些问题。
2:Timer创建的线程没有处理异常,因此一旦抛出非受检异常,该线程会立即终止。
JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。该类属于Executor Framework,它除了能处理异常外,还可以创建多个线程解决上面的问题。
下面利用ScheduledThradPoolExecutor实现同一个功能。
import java.awt.Toolkit; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ExecutorDemo { public static void main(String... args) { ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(10); MyTask myTask = new MyTask(); stpe.scheduleWithFixedDelay(myTask, 5,1,TimeUnit.SECONDS); } private static class MyTask implements Runnable { private Toolkit toolKit; private int count; public MyTask() { toolKit = Toolkit.getDefaultToolkit(); } @Override public void run() { if(count == 10) { System.out.println("Termination!"); System.exit(1); } toolKit.beep(); System.out.println("Beep--------"); count++; } } }