Introduction to java.util.Timer and simple usage examples

1. Introduction

Timer (Timer) is a utility class for scheduling tasks (java.util.TimerTask) to be executed after a specified time or repeated at specified intervals. It can be used to perform operations such as timing tasks, timing scheduling, and time delays.

Timer (Timer) can be applied to many scenarios, such as:

Scheduling tasks (fixed rate) : When you need to perform tasks according to the scheduled time, you can use timers. For example, data backup is performed every morning, reports are generated regularly, notifications are sent regularly, etc. That is, the two overloaded methods of scheduleAtFixedRate.

Timeout handling (fixed delay) : When you need to handle the timeout of an operation, you can use a timer. For example, set the timeout period of an operation, and if it is not completed within the specified time, execute the corresponding timeout processing logic. That is, the four overloaded methods of schedule.

Timers in Java: java.util.Timer , its common methods:

Java 8 Chinese Edition - Online API Manual - Coding Tool

Modifier and Type

Method and Description

Parameter Description

void

cancel()

Terminates this timer, discarding any currently scheduled tasks.

/

int

purge()

Removes all canceled tasks from this timer's task queue.

/

void

schedule(TimerTask task, Date time)

Schedule the specified task to execute at the specified time. If this time has passed, schedule the task to execute immediately

task: the task to be scheduled

time : time to execute the task

void

schedule(TimerTask task, Date firstTime, long period)

 Performs repeated  fixed-delay executions of the specified task, starting at the specified  time  .

task: the task to be scheduled

firstTime: the time when the task was executed for the first time

period: the time interval of the continuous task in milliseconds

void

schedule(TimerTask task, long delay)

Schedules the specified task to execute after the specified delay.

task: the task to be scheduled

delay: The time to delay in milliseconds before executing the task

void

schedule(TimerTask task, long delay, long period)

Starting after the specified  delay  , re-executes  the specified task that was executed with a fixed delay .

task: the task to be scheduled

delay: The time to delay in milliseconds before executing the task

period: the time interval of the continuous task in milliseconds

void

scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

Performs repeated, fixed-rate executions  of the specified task,  starting at the specified time   .

task: the task to be scheduled

firstTime: the time when the task was executed for the first time

period: the time interval of the continuous task in milliseconds

void

scheduleAtFixedRate(TimerTask task, long delay, long period)

Begins after the specified delay   , re-executing  the specified task at a fixed rate .

task: the task to be scheduled

delay: The time to delay in milliseconds before executing the task

period: the time interval of the continuous task in milliseconds

2. The difference between schedule and scheduleAtFixedRate method

These two methods are task scheduling methods. The difference between them is that the schedule will ensure that the interval between tasks is strictly executed according to the defined period parameter. If a certain scheduling time is relatively long, then the subsequent time will be postponed to ensure the scheduling interval They are all period, and scheduleAtFixedRate is strictly in accordance with the scheduling time. If a certain scheduling time is too long, then the interval will be shortened to ensure that the next scheduling will be executed at the scheduled time. Take a chestnut: you schedule once every 3 seconds, then the normal time is 0,3,6,9s, if the second scheduling takes 2s, if it is a schedule, it will become 0,3+2 For times like ,8,11, the interval is guaranteed, and scheduleAtFixedRate will become 0,3+2,6,9, the interval is compressed, and the scheduling time is guaranteed.

3. Timer (Timer) using steps

To implement a timed task, we only need to implement the run method of TimerTask. Each task has the next execution time nextExecutionTime (milliseconds). If it is a periodic task, then each execution will update this time as the next execution time. When nextExecutionTime is less than the current time, it will be executed.

(1) The first step: create a Timer.

(2) The second step: create a TimerTask.

(3) The third step: use Timer to execute TimerTask.

The third step is undoubtedly what we are most concerned about at present, that is, timer.schedule(myTask, 2000L, 1000L). What he means is that myTask starts executing for the first time after two seconds, and then every second. This is just the most basic usage. It reflects the process of Timer timing execution.

Example 1 : Timeout handling (fixed delay)

Start executing after 2 seconds, only once

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimeTest {
    public static void main(String[] args) {
        System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));

        Timer timer = new Timer();  // (1)第一步:创建一个Timer。
        timer.schedule(new TimerTask() {  // (2)第二步:创建一个TimerTask。(3)第三步:使用Timer执行TimerTask。
            @Override
            public void run() {
                System.out.println("Timer is running");
                System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
            }
        }, 2000);
    }
}

operation result:

Current time: 2023-08-19 22-45-46:161

Timer is running

Current time: 2023-08-19 22-45-48:169

Example 2 : Scheduling tasks (fixed rate)

To perform periodic tasks, you only need to add the third parameter period of the schedule.

Start executing after 2 seconds and execute every 1 second

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimeTest {
    public static void main(String[] args) {
        System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));

        Timer timer = new Timer(); // (1)第一步:创建一个Timer。
        timer.schedule(new TimerTask() { // (2)第二步:创建一个TimerTask。(3)第三步:使用Timer执行TimerTask。
            @Override
            public void run() {
                System.out.println("Timer is running");
                System.out.println("当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
            }
        }, 2000, 1000);
    }
}

operation result:

Current time: 2023-08-19 22-48-10:190

Timer is running

Current time: 2023-08-19 22-48-12:200

Timer is running

Current time: 2023-08-19 22-48-13:203

Timer is running

Current time: 2023-08-19 22-48-14:216

Example 3 : 2 Timer instances schedule tasks (fixed rate)

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimeTest {
    public static void main(String[] args) {
        System.out.println("timer当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
        Timer timer = new Timer(); // (1)第一步:创建一个Timer。
        timer.schedule(new TimerTask() { // (2)第二步:创建一个TimerTask。(3)第三步:使用Timer执行TimerTask。
            @Override
            public void run() {
                System.out.println("Timer is running");
                System.out.println("timer当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
            }
        }, 2000, 1000);

        System.out.println("timer2当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
        Timer timer2 = new Timer(); // (1)第一步:创建一个Timer。
        timer2.schedule(new TimerTask() { // (2)第二步:创建一个TimerTask。(3)第三步:使用Timer执行TimerTask。
            @Override
            public void run() {
                System.out.println("Timer2 is running");
                System.out.println("timer2当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH-mm-ss:SSS").format(new Date()));
            }
        }, 3000, 2000);
    }
}

operation result:

timer current time: 2023-08-20 00-08-06:746

Timer2 current time: 2023-08-20 00-08-06:748

Timer is running

timer current time: 2023-08-20 00-08-08:750

Timer is running

Timer2 is running

Timer2 current time: 2023-08-20 00-08-09:755

timer current time: 2023-08-20 00-08-09:755

Timer is running

timer current time: 2023-08-20 00-08-10:769

Timer2 is running

Timer2 current time: 2023-08-20 00-08-11:768

Timer is running

timer current time: 2023-08-20 00-08-11:784

Timer is running

timer current time: 2023-08-20 00-08-12:787

Timer2 is running

Timer2 current time: 2023-08-20 00-08-13:770

4. Defects of Timer

1. Since there is only one thread for executing tasks, if the execution time of a certain task is too long, the timing accuracy of other tasks will be destroyed. For example, if one task is executed every 1 second, and another task takes 5 seconds to execute, then if it is a fixed-rate task, it will be executed 5 times after the task is completed in 5 seconds, and the fixed-delay task will lose 4 executions.

2. If an exception is thrown during the execution of a certain task, the execution thread will terminate, causing other tasks in the Timer to no longer be executed.

3. Timer uses absolute time, that is, a certain point in time, so its execution depends on the system time. If the system time is modified, the task may not be executed.

5. A Better Alternative

Due to the defects mentioned above in Timer, in JDK1.5, we can use ScheduledThreadPoolExecutor to replace it, use Executors.newScheduledThreadPool factory method or use the constructor of ScheduledThreadPoolExecutor to create timed tasks, which are based on the implementation of thread pool and will not There are the above problems with Timer, when the number of threads is 1, it is equivalent to Timer.

Guess you like

Origin blog.csdn.net/xijinno1/article/details/132386799