ScheduledExecutorServiceクラスscheduleWithFixedDelay()とscheduleFixedRate()の違い

3013 ワード

まずscheduleWithFixedDelay()と言いますが、
scheduleWithFixedDelayは文字通り、スレッドタスクを固定遅延(時間)で実行することと理解され、実際にはスレッドタスクの実行時間にかかわらず、毎回タスクの実行が完了した後に固定時間を遅延してから次の実行を行う.
scheduleFixedRateは、スレッドタスクを固定周波数で実行します.固定周波数の意味は、スレッドタスクを完了するために設定された固定時間が不足している可能性がありますが、設定された遅延時間に達したら次の実行になります.
皆さんが理解したかどうか分かりませんが、以下は例です.
 
public static void scheduleWithFixedDelay() {

	final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
	//     
	final Runnable beeper = new Runnable() {
		public void run() {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			long time = (long) (Math.random() * 1000);
			//                     
			System.out.println(sf.format(new Date())+"  :"+Thread.currentThread().getName()+":Sleeping"+time+"ms");
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
			}
			}
		};
		//         ,  10s  ,         10s       
		final ScheduledFuture> sFuture=scheduledExecutorService.scheduleWithFixedDelay(beeper,10,10,TimeUnit.SECONDS);

		// 40s       
		scheduledExecutorService.schedule(new Runnable() {
			public void run() {
				sFuture.cancel(true);
				scheduledExecutorService.shutdown();
			}
		}, 40, TimeUnit.SECONDS);

	}

実行結果:
2013-10-16 10:45:51スレッド:pool-1-thread-2:Sleeping 726 ms 2013-10-16 10:46:02スレッド:pool-1-thread-2:Sleeping 288 ms 2013-10-16 10:46:12スレッド:pool-1-thread-2:Sleeping 294 ms
実行結果の数から見ると3回しか実行されていない.タスクの実行が完了するたびに次の実行が行われるため、40 sは10 sの遅延時間で4回実行できない.
 
 
public static void scheduleAtFixedRate() {
	//      
	final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
	//     
	final Runnable beeper = new Runnable() {
		public void run() {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			long time = (long) (Math.random() * 1000);
			//                     
			System.out.println(sf.format(new Date()) + "   :" + Thread.currentThread().getName() + ":Sleeping " + time + "ms");
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
			}
		}
	};
	//     ,    10s   10s       
	final ScheduledFuture> beeperHandle = scheduledExecutorService.scheduleAtFixedRate(beeper, 10, 10, TimeUnit.SECONDS);

	//          
	final Runnable cancelBeeper = new Runnable() {
		public void run() {
			System.out.println(Thread.currentThread().getName() + "CANCEL...");
			beeperHandle.cancel(true);
			scheduledExecutorService.shutdown();
		}
	};
	// 60s   scheduleAtFixedRate
	scheduledExecutorService.schedule(cancelBeeper, 40, TimeUnit.SECONDS);
}

 
実行結果:
2013-10-16 10:16:50スレッド:pool-1-thread-1:Sleeping 868 ms 2013-10-16 10:17:00スレッド:pool-1-thread-1:Sleeping 587 ms 2013-10-16 10:17:10スレッド:pool-1-thread-1:Sleeping 313 ms 2013-10-16 10:17:20スレッド:pool-1-thread-1:Sleeping 969 ms pool-1-thread-1 CANCEL...
時間を見ると、10 sごとに次の実行が行われていることがわかります.