Java 定时线程池各个方法的区别 Java周期执行线程池各个方法的区别 ScheduledExecutorService schedulerService
一、概述
Java JDK提供的java.util.concurrent.Executors 线程池工具类中,有四个线程池创建的方法,分别是:
- newFixedThreadPool (固定数目线程的线程池)
- newCachedThreadPool (可缓存线程的线程池)
- newSingleThreadExecutor (单线程的线程池)
- newScheduledThreadPool (定时及周期执行的线程池)
本文将整理 newScheduledThreadPool 定时线程池中各个方法的区别。
二、方法区别
1、scheduler , 无返回值
/**
* Description: schedule 方法,只执行一次 , 没有返回值
* @param executor
* @return void
* @version v1.0
* @author wu
* @date 2023/2/27 22:27
*/
public static void schedulerNoReturn(ScheduledExecutorService executor){
// 1、schedule 方法,只执行一次 , 没有返回值
executor.schedule(()->{
System.out.println("schedulerNoReturn ==");
},1, TimeUnit.SECONDS);
}
2、scheduler , 有返回值
/**
* Description: schedule 方法,只执行一次 , 没有返回值
* @param executor
* @return void
* @version v1.0
* @author wu
* @date 2023/2/27 22:27
*/
public static String schedulerYesReturn(ScheduledExecutorService executor) throws ExecutionException, InterruptedException {
// 1、schedule 方法,只执行一次 , 没有返回值
final ScheduledFuture<String> future = executor.schedule(() -> {
System.out.println("schedulerYesReturn ==");
return DateUtils.getDateTime();
}, 1, TimeUnit.SECONDS);
return future.get();
}
3、固定时间执行: scheduleAtFixedRate --- 延迟5秒测试
/**
* Description: 固定时间执行 , 和当前任务是否执行完毕 无关
* @param executor
* @param expireTime --- 过期时间,单位:秒
* @return void
* @version v1.0
* @author wu
* @date 2023/2/27 22:39
*/
public static void scheduleAtFixedRateTest(ScheduledExecutorService executor , long expireTime){
// 2、固定时间执行 , 每隔5s 执行一次 。 sleep > delay 时,以 sleep 为准
// sleep < delay , 以 delay 为准
executor.scheduleAtFixedRate(()->{
try {
TimeUnit.SECONDS.sleep(expireTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("scheduleAtFixedRate ===·"+ DateUtils.getDateTime());
},1,5,TimeUnit.SECONDS);
}
3.1、测试 - 固定执行时间5s :
scheduleAtFixedRateTest(executor,4L); // 小于
scheduleAtFixedRateTest(executor,5L); // 等于
scheduleAtFixedRateTest(executor,6L); // 大于
3.2、测试结果分别如下:
--- 方法执行时间为: 4s
scheduleAtFixedRate ===·2023-03-26 19:34:19
scheduleAtFixedRate ===·2023-03-26 19:34:24
scheduleAtFixedRate ===·2023-03-26 19:34:29
scheduleAtFixedRate ===·2023-03-26 19:34:34
--- 方法执行时间为: 5s
scheduleAtFixedRate ===·2023-03-26 19:36:02
scheduleAtFixedRate ===·2023-03-26 19:36:07
scheduleAtFixedRate ===·2023-03-26 19:36:12
scheduleAtFixedRate ===·2023-03-26 19:36:17
--- 方法执行时间为: 6s
scheduleAtFixedRate ===·2023-03-26 19:39:04
scheduleAtFixedRate ===·2023-03-26 19:39:10
scheduleAtFixedRate ===·2023-03-26 19:39:16
scheduleAtFixedRate ===·2023-03-26 19:39:22
4、固定时间执行+延迟时间后,再执行 : scheduleWithFixedDelay
/**
* Description: 固定时间执行,当前任务执行完毕后,再间隔 delay 秒后执行
* @param executor
* @param expireTime --- 过期时间,单位:秒
* @return void
* @version v1.0
* @author wu
* @date 2023/2/27 22:41
*/
public static void scheduleWithFixedDelayTest(ScheduledExecutorService executor , long expireTime){
// 3、固定时间执行,当前任务执行完毕后,再间隔 delay 秒后执行
// 下次执行时间为: sleep + delay
executor.scheduleWithFixedDelay(()->{
try {
TimeUnit.SECONDS.sleep(expireTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("scheduleWithFixedDelay ===·"+ DateUtils.getDateTime());
},1,5,TimeUnit.SECONDS);
}
4.1、测试 - 固定执行时间5s :
scheduleWithFixedDelayTest(executor,4L); // 小于
scheduleWithFixedDelayTest(executor,5L); // 等于
scheduleWithFixedDelayTest(executor,6L); // 大于
4.2、测试结果分别如下:
--- 方法执行时间为: 4s
scheduleWithFixedDelay ===·2023-03-26 19:44:11
scheduleWithFixedDelay ===·2023-03-26 19:44:20
scheduleWithFixedDelay ===·2023-03-26 19:44:29
scheduleWithFixedDelay ===·2023-03-26 19:44:38
--- 方法执行时间为: 5s
scheduleWithFixedDelay ===·2023-03-26 19:46:00
scheduleWithFixedDelay ===·2023-03-26 19:46:10
scheduleWithFixedDelay ===·2023-03-26 19:46:20
scheduleWithFixedDelay ===·2023-03-26 19:46:30
--- 方法执行时间为: 6s
scheduleWithFixedDelay ===·2023-03-26 19:47:33
scheduleWithFixedDelay ===·2023-03-26 19:47:44
scheduleWithFixedDelay ===·2023-03-26 19:47:55
scheduleWithFixedDelay ===·2023-03-26 19:48:06
三、总结
1、定时线程池中,四个方法位于 ScheduledExecutorService 类中
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
2、schedule 的两个方法特点是:
只执行一次,可以根据实际需要,有返回值和无返回值。
3、scheduleAtFixedRate :
固定速率执行, 当方法执行时间 > period 时,则会按照 方法执行时间 周期的速率进行执行 ; 当方法执行时间 <= period 时,则按照 period 周期速率执行。 【二 - 3.2、测试结果分别如下】
4、scheduleWithFixedDelay :
固定速率执行,执行的周期速率为:方法执行时间 + period 。 【二 - 4.2、测试结果分别如下】
5、scheduleAtFixedRate 和 scheduleWithFixedDelay 区别:
- scheduleAtFixedRate : 方法执行时间 > period ,会按照 方法执行时间 周期执行。
- scheduleWithFixedDelay : 方法执行完毕后,等待 period 时间后,再次执行。
6、完整的测试代码
public static void main(String[] args) throws ExecutionException, InterruptedException {
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
System.out.println(Thread.currentThread().getName()+" === start ," +DateUtils.getDateTime());
// 1、scheduler ,无返回值测试
// schedulerNoReturn(executor);
// 2、scheduler ,有返回值测试
// final String s = schedulerYesReturn(executor);
// System.out.println("scheduler ,有返回值测试:"+s);
// 3、、固定时间执行 expireTime > delay 时,以 period 为准
// scheduleAtFixedRateTest(executor,4L); // 小于
// scheduleAtFixedRateTest(executor,5L); // 等于
// scheduleAtFixedRateTest(executor,6L); // 大于
// 4、固定时间执行,当前任务执行完毕后,再间隔 delay 秒后执行
// scheduleWithFixedDelayTest(executor,4L); // 小于
// scheduleWithFixedDelayTest(executor,5L); // 等于
scheduleWithFixedDelayTest(executor,6L); // 大于
System.out.println(Thread.currentThread().getName()+" === end , "+DateUtils.getDateTime());
}