Recently, due to the project needs, I have to use multithread technology in JAVA.
Luckly, a helpful multithread technology was created way back in JDK 1.5, the ScheduledExecutorService interface. It was derived by ExecutorService class, that can schedule commands to run after a given delay, or to execute periodically.
It has two methods that some programmers will confused at.
A. ScheduledFuture<T> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit)
B .ScheduledFuture<T> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
According to the methods' names, the former one means the command will run at fixed rate, and the latter one means the total time will be delay + command's own running time. We suppose:
- Period and delay are both 4 seconds(we call it Tp), and initialDealy is 0 seconds, which means starts immediately
- The command need 3 seconds(We call it T0) to complish.
- Both of the two methods started at 1:00:00
For Task A, the command will run at
1:00:00 /1:00:04 /1:00:08 /1:00:12 ..(because the command's only needs 3 seconds which is less than 4 seconds, so the time will be Tp+0, 2*Tp+0, 3*Tp+0.. what if it's larger than 4 seconds? aha..)
For task B, the command will run at
1:00:00/ 1:00:07 / 1:00:14 / 1:00:21 ...(the delay time refers the time after the command finished .Tp+T0, 2*(Tp+T0), 3*(Tp+T0)....)
Theory are weak, let's see the code.
1 package concurrent; 2 import static java.util.concurrent.TimeUnit.SECONDS; 3 import java.util.Date; 4 import java.util.concurrent.Executors; 5 import java.util.concurrent.ScheduledExecutorService; 6 import java.util.concurrent.ScheduledFuture; 7 8 public class ScheduledPool { 9 public static void main(String args[]){ 10 final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3); 11 12 final ScheduledFuture beeperHandler = scheduler.scheduleAtFixedRate( 13 new Task("task 1"),1,4,SECONDS); 14 15 final ScheduledFuture beeperHandler2 = scheduler.scheduleWithFixedDelay( 16 new Task("task 2"),1,4,SECONDS); 17 18 scheduler.schedule(new Runnable(){ 19 public void run(){ 20 beeperHandler.cancel(true); 21 beeperHandler2.cancel(true); 22 scheduler.shutdown(); 23 } 24 },30,SECONDS); 25 } 26 } 27 28 class Task implements Runnable{ 29 private String name; 30 public Task(String n){ 31 name = n; 32 } 33 public void run(){ 34 System.out.println(name +"run.." + new Date()); 35 try{ 36 Thread.sleep(3000); 37 }catch(InterruptedException e){ 38 e.printStackTrace(); 39 } 40 } 41 }
task 1 run.. Thu Apr 25 11:54:35 CST 2013
task 2 run.. Thu Apr 25 11:54:35 CST 2013
task 1 run.. Thu Apr 25 11:54:39 CST 2013
task 2 run.. Thu Apr 25 11:54:42 CST 2013
task 1 run.. Thu Apr 25 11:54:43 CST 2013
task 1 run.. Thu Apr 25 11:54:47 CST 2013
task 2 run.. Thu Apr 25 11:54:49 CST 2013
task 1 run.. Thu Apr 25 11:54:51 CST 2013
task 1 run.. Thu Apr 25 11:54:55 CST 2013
task 2 run.. Thu Apr 25 11:54:56 CST 2013
We can see
for task 1
the time intervals are always 4 seconds which means it's in fixed rate.
for task 2:
the time intervals are 7 sencods which is 4+3, and the 4 seconds means the delay time.
Back to the question we left before, what if the running time is larger than the period in scheduleAtFixedRate method?
Just change the Task sleep time from 3000 to 5000, and the result will be
task 1 run.. Thu Apr 25 11:59:32 CST 2013
task 2 run.. Thu Apr 25 11:59:32 CST 2013
task 1 run.. Thu Apr 25 11:59:37 CST 2013
task 2 run.. Thu Apr 25 11:59:41 CST 2013
task 1 run.. Thu Apr 25 11:59:42 CST 2013
task 1 run.. Thu Apr 25 11:59:47 CST 2013
task 2 run.. Thu Apr 25 11:59:50 CST 2013
task 1 run.. Thu Apr 25 11:59:52 CST 2013
task 1 run.. Thu Apr 25 11:59:57 CST 2013
task 2 run.. Thu Apr 25 11:59:59 CST 2013
Now we can see
for task 1
the time intervals are always 5 seconds (because this time the running time is larger than the period time).
for task 2:
the time intervals are 9 sencods which is 4+5, and the 4 seconds means the delay time, the same as the previous situation.
Hope you can understand the difference between scheduleAtFixedRate and scheduleWithFixedDelay from this site.