一文带你深入了解Java中延时任务的实现

yizhihongxing

一文带你深入了解Java中延时任务的实现

延时任务(Delayed task)是一种可以在一定时间后触发的任务。在Java中,我们可以通过多种方式来实现延时任务,包括使用Timer/TimerTask类、ScheduledExecutorService类、和DelayQueue类等。

使用Timer/TimerTask类实现延时任务

Timer/TimerTask类是最早引入Java SDK中的一种实现延时任务的方式。Timer类可以以固定速率或者固定延时时间的方式执行特定任务,因此它在执行周期性的任务上非常方便。

使用Timer/TimerTask类可以通过如下简单的代码实现一个延时任务:

Timer timer = new Timer();
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        // 实现具体任务
    }
};
timer.schedule(task, 5000);

上述代码使用Timer类创建一个新的定时器,然后使用TimerTask类定义一个任务。任务会在5秒后执行,因为我们传递了延迟时间(以毫秒为单位)给schedule()方法。

需要注意的是,使用Timer类需要考虑线程安全问题,在任务执行时间过长时还需要考虑相关的问题,因此现在更常用的方式是使用ScheduledExecutorService类。

使用ScheduledExecutorService类实现延时任务

ScheduledExecutorService类是Java concurreny包中提供的线程池中的一个,它包含了几种实现延时任务的方式。与使用Timer类的方式相比,ScheduledExecutorService类更加高效和灵活。ScheduledExecutorService类中的方法可以完全替代Timer/TimerTask类中相应的方法,包括schedule()、scheduleAtFixedRate()和scuduleWithFixedDelay()等。

使用ScheduledExecutorService类可以通过如下代码实现一个延时任务:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
    @Override
    public void run() {
        // 实现具体任务
    }
};
executor.schedule(task, 5000, TimeUnit.MILLISECONDS);

上述代码使用ScheduledExecutorService类创建一个新的线程池,然后使用Runnable接口定义一个任务。任务会在5秒后执行,因为我们传递了延迟时间(以毫秒为单位)给schedule()方法。

使用DelayQueue类实现延时任务

DelayQueue类是Java集合框架中提供的一种数据结构,在内部维护了一个队列,队列中存储的元素只有在一定时间后才可以被取出。DelayQueue类主要用于实现定时任务和缓存系统。

使用DelayQueue类可以通过如下代码实现一个延时任务:

private static class DelayedTask implements Delayed {
    private final long delayTime;
    private final long expireTime;

    public DelayedTask(long delayTime) {
        this.delayTime = delayTime;
        this.expireTime = System.currentTimeMillis() + delayTime;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = expireTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        long diff = this.expireTime - ((DelayedTask) o).expireTime;
        return (int) (diff / 1000);
    }

    public void doTask() {
        // 实现具体任务
    }
}

DelayQueue<DelayedTask> queue = new DelayQueue<>();
DelayedTask task = new DelayedTask(5000);
queue.put(task);
DelayedTask taken = queue.take();
taken.doTask();

上述代码在创建一个DelayedTask类并实现Delayd接口时,使用Java时间Api的Millis时间来表示Delay的延时时间。DelayQueue队列会在take()方法取出元素时阻塞等待延时到期。在取出元素后执行其doTask()方法,实现具体任务。

示例

下面我们给出两个示例,使用ScheduledExecutorService类分别实现延时任务和周期性任务的执行:

示例一

任务在延迟3秒后执行并输出log日志:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("execute task after delay 3 seconds.");
    }
};
executor.schedule(task, 3000, TimeUnit.MILLISECONDS);

示例二

任务在延迟5秒后执行,然后每间隔2秒执行一次,直到程序结束:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("execute task periodically every 2 seconds.");
    }
};
executor.scheduleAtFixedRate(task, 5000, 2000, TimeUnit.MILLISECONDS);

本篇文章通过讲解Java中延时任务的三种实现方式,分别是使用Timer/TimerTask类、ScheduledExecutorService类、和DelayQueue类,帮助读者更加深入了解和掌握Java编程技巧,实现实际应用场景中的延时任务需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文带你深入了解Java中延时任务的实现 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Spring boot整合jsp和tiles模板示例

    当使用Spring Boot时,整合JSP和Tiles模板是非常简单的。下面是整合的完整攻略: 步骤1: 新建Spring Boot项目 首先,你需要创建一个新的Spring Boot项目。你可以在Spring Boot官网中创建一个新项目或者在Eclipse、IntelliJ IDEA等IDE中创建一个新的Spring Boot项目。 步骤2:配置pom.…

    Java 2023年6月15日
    00
  • JavaWeb项目打开网页出现Session Error的异常解决方案

    让我来详细讲解一下“JavaWeb项目打开网页出现Session Error的异常解决方案”。 问题描述 JavaWeb项目打开网页出现Session Error的异常,错误信息如下: javax.servlet.ServletException: Invalid session id 这个错误的原因是由于SessionID失效或者Session被服务器删除…

    Java 2023年5月27日
    00
  • Java 控制流程、大数值、数组

    Java 控制流程 Java 控制流程由以下几个部分构成: if…else 语句 switch 语句 for 循环 while 循环 do…while 循环 if…else 语句 if…else 语句是 Java 中最基础的流程控制语句之一,它的语法如下: if (condition) { // 条件成立执行的代码块 } else { // …

    Java 2023年5月23日
    00
  • Spring MVC 自定义数据转换器的思路案例详解

    Spring MVC 自定义数据转换器的思路案例详解 Spring MVC 是一个非常流行的 Java Web 框架,它提供了很多便捷的功能,其中包括数据转换器。数据转换器可以将请求参数转换为 Java 对象,或将 Java 对象转换为响应参数。Spring MVC 默认提供了很多数据转换器,但有时候我们需要自定义数据转换器来满足特定的需求。本文将详细讲解 …

    Java 2023年5月18日
    00
  • java基础详细笔记之异常处理

    Java基础详细笔记之异常处理 在Java编程中,程序出现异常是经常发生的事情。如果程序出现异常而未被妥善处理,那么程序将会崩溃,导致应用程序无法继续运行。所以Java提供了异常机制,它允许我们在程序中去处理异常情况,从而使得程序可以正常地继续执行。 异常的分类 Java中将异常分为两类: 可查异常,如IO异常、SQL异常等。它们必须在程序中进行处理,否则编…

    Java 2023年5月19日
    00
  • Spring JdbcTemplate整合使用方法及原理详解

    针对「Spring JdbcTemplate整合使用方法及原理详解」这个话题,我将为你提供详细的攻略,包括使用方法和原理的详细解释,并给出两条示例说明。 概述 Spring JdbcTemplate 是 Spring 框架中对 JDBC API 的抽象和封装,可以让开发者通过简单的 API 轻松地访问数据库。它提供了对事务处理的支持,能够提供可靠的处理机制,…

    Java 2023年5月20日
    00
  • java实现在原有日期时间上加几个月或几天

    下面是java实现在原有日期时间上加几个月或几天的完整攻略。 1. 使用Java 8中的LocalDate类 在Java 8中,可以使用LocalDate类来对日期进行操作。下面是一个示例代码,将当前日期加上三天并输出加完之后的日期。 LocalDate today = LocalDate.now(); // 获取当前日期 LocalDate newDate…

    Java 2023年5月20日
    00
  • Java 如何抛出自定义的异常?

    Java语言中,自定义异常可以通过继承Exception或者其子类RuntimeException实现。通过自定义异常,可以使得代码结构更加清晰,异常情况得到更加准确的处理。下面是Java如何抛出自定义异常的详细攻略。 继承Exception类实现自定义异常 首先,定义自定义异常类时,需要继承Exception类,如下所示: public class Cus…

    Java 2023年4月27日
    00
合作推广
合作推广
分享本页
返回顶部