Step by Step Multithreaded-Timer

Timer can be used to perform timed tasks. Now let's summarize what we've learned. Let's start with demo

 1 public class TimerTest {
 2 
 3     public static void main(String[] args) throws ParseException {
 4         Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
 5         new Timer().schedule(new TimerTask() {
 6             @Override
 7             public void run() {
 8                 System.out.println(new Date().getSeconds()+"  implement");
 9             }
10         }, date);
11     }
12 }

The meaning of this code is to build a Timer first, and Timer starts executing at "2017-08-17 11:18:00".

Timer Repeat Execution

The above code Timer only executes once, if we want the timed task to execute at regular intervals?Another overloaded public void schedule(TimerTask task, long delay, long period) can be used with the schedule method provided by Timer.This means that Timer starts executing at the time of the delay and executes every period time.

 1 public class TimerTest {
 2 
 3     public static void main(String[] args) throws ParseException {
 4         Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
 5         new Timer().schedule(new TimerTask() {
 6             @Override
 7             public void run() {
 8                 System.out.println(new Date().getSeconds()+"  implement");
 9             }
10         }, date,1000);
11     }
12 }

results of enforcement

37. Execution

38. Execution

39. Execution

40. Execution

  ......

Timer execution delay

When TimerTask is executed, it is possible that the thread takes too long to execute, exceeding Timer's wait time.What happens at this point?

  

 1 public class TimerTest {
 2 
 3     public static void main(String[] args) throws ParseException {
 4         Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
 5         new Timer().schedule(new TimerTask() {
 6             @Override
 7             public void run() {
 8                 System.out.println(new Date().getSeconds()+"  Start execution");
 9                 try {
10                     Thread.sleep(2000);
11                     System.out.println(new Date().getSeconds()+"  end of execution");
12                 } catch (InterruptedException e) {
13                     e.printStackTrace();
14                 }
15             }
16         }, date,1000);
17     }
18 }

See execution results

0 Start execution

2. End of execution

2. Start execution

4. End of execution

4. Start execution

6. End of execution

6. Start execution

8. End of execution

8. Start execution

scheduleAtFixedRate

Timer tasks are executed using the schedule method, and Timer does not supplement tasks that were not previously executed if the start time was before the current time.That is, after the delay, the Timer starts at the current time and then executes at intervals.But sometimes our needs are more focused on the frequency of execution, and we need to replenish tasks that were not performed because of delays, so we need to use scheduleAtFiexdRate.

 1 public class TimerTest {
 2 
 3     public static void main(String[] args) throws ParseException {
 4         final Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:52:00");
 5         new Timer().scheduleAtFixedRate(new TimerTask() {
 6             @Override
 7             public void run() {
 8                 System.out.println(date);
 9                 System.out.println(new Date().getSeconds() + "  Start execution");
10                 System.out.println("Executed");
11                 System.out.println(new Date().getSeconds() + "  end of execution");
12 
13             }
14         }, date, 10000);
15     }
16 }

Execution results

39. Start execution

- Executed

39. End of execution

  Thu Aug 17 11:52:00 CST 2017

39. Start execution

- Executed

39. End of execution

  Thu Aug 17 11:52:00 CST 2017

40 Start execution

- Executed

40 End of execution

 

From the execution results, it can be seen that the missing executions are first filled up on the scheduleAtFixedRate, and then the execution is started once at an interval.

Set Timer to Daemon Thread

 1 public class TimerTest {
 2 
 3     public static void main(String[] args) throws ParseException {
 4         final Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:52:00");
 5         Timer timer=new Timer();
 6         TimerTask timerTask= new TimerTask() {
 7             @Override
 8             public void run() {
 9                 System.out.println(date);
10                 System.out.println(new Date().getSeconds() + "  Start execution");
11                 System.out.println("Executed");
12                 System.out.println(new Date().getSeconds() + "  end of execution");
13 
14             }
15         };
16         timer.schedule(timerTask, date);
17     }
18 }

 

After executing the code, the program is still running.Looking at the source code for Timer.class, you can see that Timer created a new thread, and continuous code tracking found that the new thread made a while(true) loop and entered a wait state.

1 public Timer(String name) {
2     thread.setName(name);
3     thread.start();
4 }

Solution

Set Timer as a daemon thread, Timer has a constructor.

1 public Timer(boolean isDaemon) {
2     this("Timer-" + serialNumber(), isDaemon);
3 }

So we can just change the new Timer() to the new Timer(true).

TimerTask and Timer cancel methods

TimerTask's cancel method closes this task, Timer's cancel method closes the entire Timer.

Timer's execution actually starts a thread, maintains a queue in the thread, and puts the TimerTask in the queue.TimerTask's cancel method is to remove itself from the task queue.Timer's cancel method is to empty all tasks in the queue.

Keywords: Java

Added by Zpixel on Mon, 03 Jun 2019 22:48:30 +0300