使用ScheduledThreadPoolExecutor代替Timer&TimerTask
程序员文章站
2022-07-15 09:22:21
...
如果我们想要延迟(deferred)或者周期性(periodic)执行一个任务,我们可以使用Java API 的Timer和TimerTask类。
一般步骤是:
继承TimerTask(抽象类),复写run方法,方法体里代表需要执行的任务。
实例化Timer(可以通过构造方法设置为守护线程),调用schedule的一个重载方法实现延迟或者周期性执行自定义任务。
下面的例子演示了程序启动5秒后每隔1秒警报器叫一声,10次后终止程序执行。
Java代码
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秒钟
}
}
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实现同一个功能。
Java代码
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++;
}
}
}
一般步骤是:
继承TimerTask(抽象类),复写run方法,方法体里代表需要执行的任务。
实例化Timer(可以通过构造方法设置为守护线程),调用schedule的一个重载方法实现延迟或者周期性执行自定义任务。
下面的例子演示了程序启动5秒后每隔1秒警报器叫一声,10次后终止程序执行。
Java代码
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秒钟
}
}
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实现同一个功能。
Java代码
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++;
}
}
}
推荐阅读
-
请教.HTML使用_框架_能做到如下效果么?如果不能可以使用什么来代替框架呢? 问题内详_html/css_WEB-ITnose
-
在SQL查询中使用LIKE来代替IN查询的方法
-
如何使用localstorage代替cookie实现跨域共享数据问题
-
在SQL查询中使用LIKE来代替IN查询的方法
-
Python中使用logging模块代替print(logging简明指南)
-
MVC使用Controller代替Filter完成登录验证(Session校验)学习笔记5
-
Android 使用FragmentTabhost代替Tabhost
-
如何使用localstorage代替cookie实现跨域共享数据问题
-
VMware Workstation/Fusion 中安装 Fedora 23/24 及其他 Linux 系统时使用 Open VM Tools 代替 VMware Tools 增强工具的方法
-
编写高质量代码改善C#程序——使用泛型集合代替非泛型集合(建议20)