`
Everyday都不同
  • 浏览: 723551 次
  • 性别: Icon_minigender_1
  • 来自: 宇宙
社区版块
存档分类
最新评论

ScheduledExecutorService的scheduleAtFixedRate和scheduleWithFixedDelay方法的区别

阅读更多

ScheduledExecutorService是java.util.concurrent并发包下的一个接口,表示调度服务~,它定义了以下几个方法:

 

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个的任务是指定在延迟时间后执行一次任务,后2个方法则表示每间隔一段时间定时执行任务。

ScheduledExecutorService的后两个方法比较容易搞混,下面就用小例子来搞清楚:

 

public class DiffTest {
	
	private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
	
	public static void main(String[] args) {
		final long executeTime = (long) (Math.random()*10);
		
		
		//scheduleAtFixedRate
		executor.scheduleAtFixedRate(new Runnable(){
			//模拟耗时任务,耗时是10s以内的任意数
			@Override
			public void run() {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
					System.out.print(sdf.format(new Date()) + " 开始执行, ");
					Thread.sleep(3000);//3s
					System.out.println(sdf.format(new Date()) + "结束执行 ================");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		}, 0, 5, TimeUnit.SECONDS);//每隔5s
		
		
	}
	
}

 当间隔时间(5s)大于任务的执行时间(3s),运行结果为:

 

12:00:03 开始执行, 12:00:06结束执行 ================

12:00:08 开始执行, 12:00:11结束执行 ================

12:00:13 开始执行, 12:00:16结束执行 ================

12:00:18 开始执行, 12:00:21结束执行 ================

12:00:23 开始执行, 12:00:26结束执行 ================

12:00:28 开始执行, 12:00:31结束执行 ================

 

当间隔时间(5s)小于程序(7s)执行时间(将耗时改为7s, 每隔5s的设置就会失效)

12:01:26 开始执行, 12:01:33结束执行 ================

12:01:33 开始执行, 12:01:40结束执行 ================

12:01:40 开始执行, 12:01:47结束执行 ================

12:01:47 开始执行, 12:01:54结束执行 ================

12:01:54 开始执行, 12:02:01结束执行 ================

12:02:01 开始执行, 12:02:08结束执行 ================

说明:scheduleAtFixedRate是以上一次任务的开始时间为间隔的,并且当任务执行时间大于设置的间隔时间时,真正间隔的时间由任务执行时间为准!

 

再来测试下scheduleWithFixedDelay:

executor.scheduleWithFixedDelay(new Runnable(){
			//模拟耗时任务,耗时是10s以内的任意数
			@Override
			public void run() {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
					System.out.print(sdf.format(new Date()) + " 开始执行, ");
					Thread.sleep(3000);//3s
					System.out.println(sdf.format(new Date()) + "结束执行 ================");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		}, 0, 5, TimeUnit.SECONDS);//每隔5s

  当间隔时间(5s)大于任务的执行时间(3s),运行结果为:

12:46:54 开始执行, 12:46:57结束执行 ================

12:47:02 开始执行, 12:47:05结束执行 ================

12:47:10 开始执行, 12:47:13结束执行 ================

12:47:18 开始执行, 12:47:21结束执行 ================

12:47:26 开始执行, 12:47:29结束执行 ================

 

12:47:34 开始执行, 12:47:37结束执行 ================

 

当间隔时间(5s)小于程序(7s)执行时间,此时运行结果为:

12:48:12 开始执行, 12:48:19结束执行 ================

12:48:24 开始执行, 12:48:31结束执行 ================

12:48:36 开始执行, 12:48:43结束执行 ================

12:48:48 开始执行, 12:48:55结束执行 ================

12:49:00 开始执行, 12:49:07结束执行 ================

12:49:12 开始执行, 12:49:19结束执行 ================

说明:scheduleWithFixedDelay是以上一次任务的结束时间为间隔的!

 

顺便说下,当定时调度遇到异常时,是否会影响下次任务的执行:

public class DiffTest {
	
	private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
	
	private static int  a;
	
	private static int[] aa = {1,2,3};
	
	public static void main(String[] args) {
		
		//scheduleAtFixedRate
		executor.scheduleWithFixedDelay(new Runnable(){
			//模拟耗时任务,耗时是10s以内的任意数
			@Override
			public void run() {
				try {
					SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
					System.out.println(sdf.format(new Date()) + " 开始执行");
					System.out.println("执行结果:" + aa[a++]);
					System.out.println("==============");
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		}, 0, 5, TimeUnit.SECONDS);//每隔5s
	}
}

 运行之,结果为:

19:13:07 开始执行

执行结果:1

==============

19:13:12 开始执行

执行结果:2

==============

19:13:17 开始执行

执行结果:3

==============

19:13:22 开始执行

java.lang.ArrayIndexOutOfBoundsException: 3

at com.nineclient.echat.plugin.DiffTest$1.run(DiffTest.java:28)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)

at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

at java.lang.Thread.run(Thread.java:722)

19:13:27 开始执行

java.lang.ArrayIndexOutOfBoundsException: 4

at com.nineclient.echat.plugin.DiffTest$1.run(DiffTest.java:28)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)

at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

at java.lang.Thread.run(Thread.java:722)

这说明,虽然执行到第4次时发生了异常,但并不影响下一次的执行。但如果你没有异常捕获机制,则会影响,比如改成:

executor.scheduleWithFixedDelay(new Runnable(){
			//模拟耗时任务,耗时是10s以内的任意数
			@Override
			public void run() {
				SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
				System.out.println(sdf.format(new Date()) + " 开始执行");
				System.out.println("执行结果:" + aa[a++]);
				System.out.println("==============");
			}
			
		}, 0, 5, TimeUnit.SECONDS);//每隔5s

 运行结果为:

19:14:39 开始执行

执行结果:1

==============

19:14:44 开始执行

执行结果:2

==============

19:14:49 开始执行

执行结果:3

==============

19:14:54 开始执行

 

 

之后就不再运行了。。所以务必在被调度的任务上加上异常捕获!

分享到:
评论

相关推荐

    基于ScheduledExecutorService的两种方法(详解)

    ScheduledExecutorService提供了两种方法来实现定时任务的执行,分别是scheduleAtFixedRate和scheduleWithFixedDelay。 scheduleAtFixedRate方法 scheduleAtFixedRate方法用于实现定时任务的执行,例如,每隔3秒...

    ScheduledExecutorService任务定时代码示例

    ScheduledExecutorService 任务定时代码示例 ScheduledExecutorService 是 ...ScheduledExecutorService 提供了多种方法来执行任务,如 scheduleAtFixedRate、scheduleWithFixedDelay 等,可以满足不同的业务需求。

    几种定时任务(Timer、TimerTask、ScheduledFuture)的退出—结合真实案例【JAVA并发】.docx

    然后,我们可以通过ScheduledExecutorService的scheduleWithFixedDelay()或scheduleAtFixedRate()方法来安排任务。例如,使用Runnable来实现定时任务: ```java ScheduledFuture&lt;?&gt; future = ...

    ScheduledExecutorService 计时器任务处理

    3. `scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)`: 类似于`scheduleAtFixedRate`,但区别在于两次任务执行之间的时间间隔是上一次任务结束到下一次任务开始的时间,而...

    定时修改域名解析记录, 下载后先看说明呀

    你需要定义一个Runnable或Callable任务,其中包含更新DNS记录的逻辑,然后通过ScheduledExecutorService的scheduleAtFixedRate或scheduleWithFixedDelay方法设置执行间隔。 4. **异常处理与重试策略**:考虑到网络...

    WebService 定时任务 任务预警

    开发者可以创建一个ScheduledThreadPoolExecutor实例,然后通过其scheduleAtFixedRate或scheduleWithFixedDelay方法来安排周期性任务。此外,Spring框架提供了更高级的定时任务管理,如@Scheduled注解和Task...

    tomcat 定时作业

    你可以定义一个实现了Runnable或Callable接口的类,然后使用ScheduledExecutorService的scheduleAtFixedRate或scheduleWithFixedDelay方法来设置周期执行。 ```java ScheduledExecutorService executor = Executors...

    Java定时任务的三种实现方式

    通过ScheduledExecutorService的schedule、scheduleAtFixedRate和scheduleWithFixedDelay方法,开发者可以灵活地安排任务执行。 最后,Quartz是一个开源的作业调度框架,提供丰富的API和插件支持,适合大型项目中...

    android定时切换

    通过scheduleAtFixedRate或scheduleWithFixedDelay方法,可以设置定时任务,适合需要线程池管理的复杂场景。 在描述中提到的“做及时通讯播放语音”,可能涉及到以下几个关键技术点: 1. **AudioTrack**: ...

    Java线程池.docx

    Java线程池 Java线程池是Java语言中的一种高级多线程处理机制,用于避免重复创建和销毁线程而导致额外的性能开销。Java线程池功能可以实现...在上面的示例代码中,我们使用了scheduleAtFixedRate方法来执行定时任务。

    java实现一个小程序语句的延迟执行的小demo

    此外,`ScheduledExecutorService`还提供了`scheduleAtFixedRate()`和`scheduleWithFixedDelay()`方法,用于周期性地执行任务。前者会在每次任务执行结束与下一次开始之间保持恒定的时间间隔,而后者则是在任务完成...

    Android线程池管理的代码例子

    其方法`scheduleAtFixedRate`和`scheduleWithFixedDelay`可以实现定时执行任务,如下所示: ```java ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); Runnable task =...

    java Schedule

    通过`ScheduledExecutorService`,你可以使用`schedule()`, `scheduleAtFixedRate()`, 和 `scheduleWithFixedDelay()` 方法来安排一次性任务和周期性任务,并且这些任务会在单独的工作线程中执行,互不影响。...

    Java计时器

    我们可以使用`Executors`类的静态方法创建一个ScheduledExecutorService实例,然后通过`schedule()`, `scheduleAtFixedRate()` 或 `scheduleWithFixedDelay()` 方法来安排任务。ScheduledExecutorService相比Timer有...

    java schedule

    `ScheduledExecutorService`提供了一组用于延迟执行或定期执行任务的方法,如`schedule()`, `scheduleAtFixedRate()`, 和 `scheduleWithFixedDelay()`。`ScheduledThreadPoolExecutor`是实现`...

    java定时执行代码.

    - 在资源管理方面,ScheduledExecutorService更占优势,因为它允许通过`shutdown()`和`shutdownNow()`方法优雅地关闭任务执行。 总结,Java定时执行代码主要通过Timer类和ScheduledExecutorService接口来实现。...

    javaAlerter_JAVA源码_

    5. **周期性任务**:如果需要定期执行任务,可以使用`Timer.scheduleAtFixedRate()`或`ScheduledExecutorService.scheduleWithFixedDelay()`,它们会按照指定的频率重复执行任务。 6. **取消和清理**:`Timer....

    JAVA定时任务

    通过实现`Runnable`或`Callable`接口并使用`ScheduledExecutorService`的`schedule`、`scheduleAtFixedRate`和`scheduleWithFixedDelay`方法来安排任务。 2. **Timer和TimerTask** 在较早的Java版本中,`java.util...

    interval_ir

    你可以通过实现Runnable或Callable接口来创建任务,并使用ScheduledExecutorService的schedule、scheduleAtFixedRate或scheduleWithFixedDelay方法进行调度。 3. **java.time包**:自Java 8引入以来,这个包极大地...

    java线程池的源码分析.zip

    8. **`scheduleAtFixedRate()`和`scheduleWithFixedDelay()`**:两者都是`ScheduledExecutorService`的方法,用于周期性执行任务。`scheduleAtFixedRate()`按照固定的速率执行任务,即使上一次任务执行超时,下一次...

Global site tag (gtag.js) - Google Analytics