Kusch's blog Kusch's blog
首页
Java
框架
部署与运维
数据库
  • 我的电脑
  • 科学技巧
  • 杂文铺
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Mr.Kusch

入门前把门拆了的程序猿一枚
首页
Java
框架
部署与运维
数据库
  • 我的电脑
  • 科学技巧
  • 杂文铺
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础

    • 线程Run和Start
    • 范型super和extends关键字的区别
    • Timer和ScheduledExecutorService
      • Timer
      • ScheduledExecutorService
      • 总结
        • 线程安全性
        • 灵活性
        • 异常处理
        • 多任务执行
    • 重写equals和hashCode的必要性
  • Java集合

  • JavaIO

  • Java并发

  • JVM

  • Java
  • Java基础
Mr.Kusch
2023-04-24
目录

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();
    }
}
1
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();
    }
}
1
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也可以满足您的需求。

编辑 (opens new window)
#随笔
上次更新: 2023/05/28, 08:23:00
范型super和extends关键字的区别
重写equals和hashCode的必要性

← 范型super和extends关键字的区别 重写equals和hashCode的必要性→

最近更新
01
Linux与Docker的时区
05-30
02
Docker部署Sentinel
05-30
03
Git提交常用表情 转载
05-28
更多文章>
Theme by Vdoing | Copyright © 2023-2023 Mr.Kusch | MIT License | 苏ICP备20030181号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式