Java使用线程池执行定时任务(java等待线程池执行完毕)

网友投稿 374 2022-08-07


Java使用线程池执行定时任务(java等待线程池执行完毕)

目录1.schedule2.scheduleAtFixedRate3.scheduleWithFixedDelay总结

前言:

在 java 语言中,有两个线程池可以执行定时任务:ScheduledThreadPool 和 SingleThreadScheduledExecutor,其中 SingleThreadScheduledExecutor 可以看做是 ScheduledThreadPool 的单线程版本,它的用法和 ScheduledThreadPool 是一样的,所以本文重点来看 ScheduledThreadPool 线程池的使用。

ScheduledThreadPool 执行定时任务的方法有以下 3 个:

使用 schedule 方法执行定时任务,只执行一次定时任务。使用 scheduleAtFixedRate 方法执行定时任务,执行多次定时任务。使用 scheduleWithFixedDelay 方法执行定时任务,执行多次定时任务。

接下来我们看这 3 个方法的具体使用和区别。

1.schedule

schedule 方法只能执行一次定时任务,它需要传递 3 个参数:

第 1 个参数:传递一个任务,Runnable 或 Callable 对象;第 2 个参数:添加定时任务后,再过多久开始执行定时任务;第 3 个参数:时间单位,配合参数 2 一起使用。

下面我们创建一个 3 秒以后执行的定时任务:

import java.time.LocalDateTime;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {

public static void main(String[] args) throws InterruptedException {

// 创建 ScheduledThreadPool 线程池

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10);

System.out.println("schedule 方法添加任务:" + LocalDateTime.now());

threadPool.schedule(new Runnable() {

@Override

public void run() {

System.out.println("执行 schedule 方法:" + LocalDateTime.now());

}

}, 3, TimeUnit.SECONDS); // 3s 之后执行

// 以下代码是给业务方法一个时间对照信息

TimeUnit.SECONDS.sleep(10); // 休眠 10s

System.out.println("当前时间:" + LocalDateTime.now());

}

}

以上程序的执行结果如下图所示:

从上述结果中可以看出,使用 schedule 方法只能执行一次定时任务。

2.scheduleAtFixedRate

scheduleAtFixedRate 方法可以执行多次定时任务,此方法需要 4 个参数:

第 1 个参数:传递一个任务,Runnable 或 Callable 对象;第 2 个参数:添加定时任务后,再过多久开始执行定时任务;第 3 个参数:定时任务执行的时间间隔;第 4 个参数:时间单位,配合参数 2 和参数 3 一起使用。

下面我们创建一个 3 秒后执行的定时任务,每个定时任务执行的时间间隔为 2 秒,

实现代码如下:

import java.time.LocalDateTime;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {

public static void main(String[] args) throws InterruptedException {

// 创建 ScheduledThreadPool 线程池

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10);

System.out.println("scheduleAtFixedRate 方法添加任务:" + LocalDateTime.now());

threadPool.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

System.out.println("执行 scheduleAtFixedRate 方法:" + LocalDateTime.now());

http:// // 休眠 2s

try {

TimeUnit.SECONDS.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

},

3L, // 3s 后开始执行定时任务

2L, // 定时任务的执行间隔为 2s

TimeUnit.SECONDS); // 描述上面两个参数的时间单位

}

}

以上程序的执行结果如下图所示:

从上述结果可以看出,当任务添加成功之后,3s 后开始执行第一个定时任务,之后每隔 2s 执行一次定时任务。

3.scheduleWithFixedDelay

scheduleWithFixedDelay 方法的使用和 scheduleAtFixedRate 类似,但执行效果完全不同,这个很容易理解如果效果一样就不用创建两个方法了。 scheduleWithFixedDelay 方法是在方法执行完成之后,再隔 N 秒执行下一个定时任务,和 scheduleAtFixedRate 的固定时间执行不同,scheduleWithFixedDelay 方法的执行受定时任务执行的时长影响,

比如以下代码:

import java.time.LocalDateTime;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {

public static void main(String[] args) throws InterruptedException {

// 创建 ScheduledThreadPool 线程池

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10);

System.out.println("scheduleWithFixedDelay 方法添加任务:" + LocalDateTime.now());

threadPool.scheduleWithFixedDelay(new Runnable() {

@Override

public void run() {

System.out.println("执行 scheduleWithFixedDelay 方法:" + LocalDateTime.now());

// 休眠 2s

try {

TimeUnit.SECONDS.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

},

3L, // 3s 后开始执行定时任务

2L, // 定时任务执行完 2s 之后,再执行下一个定时任务

TimeUnit.SECONDS); // 描述上面两个参数的时间单位

}

}

以上程序的执行结果如下图所示:

从上述结果可以看出,定时任务在 3s 之后开始执行,以后每隔 4s 执行一次,这 4s 包含了,定时任务执行花费的 2s,加上每隔 2s 执行一次的时间间隔,也就是说 scheduleWithFixedDelay 是在任务执行完 N 秒之后,再执行下一次定时任务。

总结

线程池执行定时任务的实现方法有 3 个:

使用 schedule 方法执行定时任务,只执行一次定时任务。使用 scheduleAtFixedRate 方法执行定时任务,执行多次定时任务,它的执行时间间隔是固定的,不受定时任务执行时长影响(定时任务时间间隔 > 任务执行时间)。使用 scheduleWithFixedDelay 方法执行定时任务,执行多次定时任务,它是在定时任务执行完之后,再隔 N 秒开始执行下一次定时任务,它的执行时间受定时任务执行时长影响。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java详解对象终止方法finalize()的用法(使用finalize()方法判断对象已死后)
下一篇:Java创建线程池为什么一定要用ThreadPoolExecutor(java线程池可以创建多少线程)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~