自学内容网 自学内容网

Java中定时任务执行的三种方式


💖The Begin💖点点关注,收藏不迷路💖

在Java中,实现定时任务执行的需求非常常见,比如定时清理缓存、定时发送邮件等。Java提供了多种机制来实现这一功能,包括使用普通线程的死循环、Timer类以及ScheduledExecutorService接口。

1. 普通线程死循环

1.1 优点

  • 实现简单,易于理解。

1.2 缺点

  • 消耗CPU资源,因为需要不断检查时间是否到达。
  • 难以精确控制时间间隔,尤其是当执行的任务耗时较长时。
  • 线程管理复杂,需要手动控制线程的启动、停止等。

1.3 示例代码片段

new Thread(() -> {  
    while (!Thread.currentThread().isInterrupted()) {  
        try {  
            Thread.sleep(1000); // 等待1秒  
            // 执行定时任务  
            System.out.println("定时任务执行:" + System.currentTimeMillis());  
        } catch (InterruptedException e) {  
            Thread.currentThread().interrupt();  
        }  
    }  
}).start();

2. 使用定时器 Timer

2.1 优点

相对于普通线程死循环,Timer可以更灵活地安排任务执行。
可以安排只执行一次的任务,也可以安排重复执行的任务。

2.2 缺点

Timer线程是Java的单线程定时器,如果有任务执行时间过长,会影响后续任务的执行时间。
Timer的线程安全性问题,如果TimerTask的run方法抛出未检查的异常,Timer会终止所有任务的执行。

2.3 示例代码片段

Timer timer = new Timer();  
timer.schedule(new TimerTask() {  
    @Override  
    public void run() {  
        // 执行定时任务  
        System.out.println("Timer定时任务执行:" + System.currentTimeMillis());  
    }  
}, 0, 1000); // 延迟0毫秒后开始执行,之后每隔1000毫秒执行一次

3. 使用定时调度线程池 ScheduledExecutorService

3.1 优点

相比Timer,ScheduledExecutorService提供了更丰富的调度选项。
它是基于线程池的,可以支持多个并发任务,且不会因为单个任务执行时间过长而影响其他任务。
线程池中的线程可以重用,减少了线程创建和销毁的开销。

3.2 缺点

相对于前两种方式,实现稍微复杂一些。

3.3 示例代码片段

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
executor.scheduleAtFixedRate(() -> {  
    // 执行定时任务  
    System.out.println("ScheduledExecutorService定时任务执行:" + System.currentTimeMillis());  
}, 0, 1, TimeUnit.SECONDS); // 初始延迟0秒后开始执行,之后每隔1秒执行一次

在这里插入图片描述


💖The End💖点点关注,收藏不迷路💖

原文地址:https://blog.csdn.net/qq_41840843/article/details/140351317

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!