一篇带你了解ScheduledExecutorService的用法和适用场景

发布于:2024-07-01 ⋅ 阅读:(11) ⋅ 点赞:(0)

希望文章能给到你启发和灵感~
如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~

开篇说明

ExecutorService大家应该不会陌生,他是是Java中用于管理和执行线程的高级工具,而今天我们说的ScheduledExecutorService是Java中用于调度任务的接口。具体来说,它是ExecutorService的子接口,扩展了线程池的功能,允许在预定的时间执行任务,也可以周期性地重复执行任务;

在这里插入图片描述

一、ScheduledExecutorService的作用

作用:

  • 在指定的延迟后执行特定的任务。
  • 按照固定的时间间隔重复执行特定的任务。
  • 提供了线程池的功能,用于更好地管理和控制线程的生命周期

二、ScheduledExecutorService的使用

2.1 常用方法

方法:

  • schedule(Runnable command, long delay, TimeUnit unit)

在给定的延迟之后运行命令。只执行一次,第一个参数定义你要执行任务线程,第二个参数是延迟的时间,第三个参数是时间单位,可以是秒,可以分,小时,天等等;

		// 创建一个单线程的ScheduledExecutorService  
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();  
  
        // 定义一个Runnable任务  
        Runnable task = new Runnable() {  
            @Override  
            public void run() {  
                System.out.println("执行我的线程逻辑");  
            }  
        };  
        // 使用schedule方法,在5秒后执行任务  
        executor.schedule(task, 5, TimeUnit.SECONDS); 
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

在指定的初始延迟后开始执行任务,并按照固定的时间间隔重复执行。多了一个间隔时间参数

		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
  
        // 定义一个Runnable任务  
        Runnable task = new Runnable() {  
            @Override  
            public void run() {  
                System.out.println("执行我的线程逻辑");  
            }  
        };  
  
        // 使用scheduleAtFixedRate方法,首次延迟0秒执行,之后每隔2秒执行一次  
        // 注意:如果任务执行时间超过间隔,那么下一次任务将立即开始,而不会等待上一个任务完成  
        executor.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

在指定的初始延迟后开始执行任务,并在每次执行完成后等待给定的延迟时间,然后再次执行任务

		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
  
        // 定义一个Runnable任务  
        Runnable task = new Runnable() {  
            @Override  
            public void run() {  
                System.out.println("执行我的线程逻辑");  
            }  
        };  
		// 首次延迟0秒执行,之后每次在上一个任务执行完成后延迟1秒执行  
		executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);

2.2 如何关闭释放资源

需要注意的是:

如果我们的任务执行完成后,需要有一个关闭的动作,就如同我们操作完流后都会执行一下close一样,虽然即使不关闭,Java自身的JVM也会帮我们回收,但是被动的操作就会有可能造成内存的泄漏的风险;

	// 当不再需要执行器时,关闭它,但不会立即关闭,而是等待所有任务完成才去执行关闭  
	executor.shutdown();   
	// 如果需要立即关闭并尝试中断任务
	executor.shutdownNow();
	// 指定等待时间来等待执行完成  
	executor.awaitTermination(long timeout, TimeUnit unit) // 如果在等待时间内执行器成功关闭,该方法将返回true;否则返回false

根据关闭的几个方法特性,我们可以根据实际使用场景来搭配使用;

三、最后

ExecutorService 和ScheduledExecutorService 的区别和共同点

【1】两者都是Java中用于管理和控制线程的重要接口

【2】ExecutorService允许提交任务并控制它们如何运行,但不提供定时或周期性任务的功能

【3】ScheduledExecutorService 是ExecutorService的子接口,是他的一个扩展;

【4】针对需求中要周期性执行的,或者一定延迟执行的任务场景,我们就能使用该接口来实现;
【5】使用ScheduledExecutorService时,需要注意任务执行时间可能超过指定的时间间隔,特别是当使用scheduleAtFixedRate方法时。如果任务执行时间超过间隔时间,该方法会立即开始下一个任务,可能导致任务连续执行;