Timer和ScheduledExecutorService
# Timer
使用Timer可以执行定时任务和周期性任务。下面是一个使用Timer的示例代码:
import java.util.Timer;
import java.util.TimerTask;
/**
* Timer 使用例子
*/
public class TimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
// 延迟1秒后执行任务
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("延迟1秒后执行任务,执行一次");
}
}, 1000);
// 延迟2秒后执行任务,然后每隔3秒重复执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("延迟2秒后执行任务,然后每隔3秒重复执行");
}
}, 2000, 3000);
// 延迟5秒后执行任务,然后每隔5秒重复执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("延迟5秒后执行任务,然后每隔5秒重复执行");
}
}, 5000, 5000);
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 关闭timer
timer.cancel();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
在这个示例中,我们首先创建了一个Timer实例。然后我们使用它的schedule()方法来执行不同的定时任务和周期性任务。
注意,在完成任务后,我们需要调用Timer的cancel()方法来关闭它。
需要注意的是,如果一个定时任务抛出了异常,Timer会停止所有任务的执行并抛出RuntimeException。
# ScheduledExecutorService
ScheduledExecutorService是Java中的一个接口,它继承自ExecutorService接口,用于执行定时任务和周期性任务。下面是一个使用ScheduledExecutorService的示例代码:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* ScheduledExecutorService使用例子
*/
public class ScheduledExecutorServiceExample {
public static void main(String[] args) {
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
// 延迟1秒后执行任务
executorService.schedule(() -> System.out.println("延迟1秒后执行任务,仅执行一次"), 1, TimeUnit.SECONDS);
// 延迟2秒后执行任务,然后每隔3秒重复执行
executorService.scheduleAtFixedRate(
() -> System.out.println("延迟2秒后执行任务,然后每隔3秒重复执行"), 2, 3,
TimeUnit.SECONDS);
// 延迟5秒后执行任务,然后每隔5秒重复执行
executorService.scheduleWithFixedDelay(
() -> System.out.println("延迟5秒后执行任务,然后每隔5秒重复执行"), 5, 5, TimeUnit.SECONDS);
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 关闭线程池
executorService.shutdown();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在这个示例代码中,我们使用了Executors类的静态方法newSingleThreadScheduledExecutor()创建了一个只有一个线程的ScheduledExecutorService实例。 然后我们通过调用它的不同方法来执行不同的定时任务和周期性任务。
注意,在完成任务后,我们需要调用ScheduledExecutorService的shutdown()方法来关闭线程池。
# 总结
ScheduledExecutorService和Timer都可以用于执行定时任务和周期性任务,但它们之间有一些区别。
# 线程安全性
ScheduledExecutorService是线程安全的,而Timer则不是。当多个线程同时访问Timer时,可能会出现竞态条件(race condition),导致任务执行时间不准确或任务被跳过。
# 灵活性
ScheduledExecutorService比Timer更灵活。例如,ScheduledExecutorService可以使用任何实现了Runnable接口的任务,而Timer只能使用TimerTask类。此外,ScheduledExecutorService还提供了更多的调度选项,如支持相对时间、绝对时间和固定速率等。
# 异常处理
ScheduledExecutorService能够处理任务中抛出的异常,而Timer不能。如果TimerTask在运行时抛出未捕获的异常,则整个Timer将停止运行,这可能会导致其他计划的任务无法执行。
# 多任务执行
ScheduledExecutorService可以同时执行多个任务,而Timer只能按顺序执行一个任务。
综合来说,如果您需要一个灵活、高效且线程安全的定时任务调度器,那么建议使用ScheduledExecutorService。当然,在某些情况下,Timer也可以满足您的需求。