Java Timer (timer)

Overview:

Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以安排任务“执行一次”或者定期“执行多次”。                 
 然而在实际的开发过程当中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。
 对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。

Method summary:

schedule(TimerTask task, Date time) // 安排在 "指定的时间" 执行 指定的任务。(只执行一次)
schedule(TimerTask task,long delay) // 安排在指定延迟后执行指定的任务
schedule(TimerTask task, Date firstTime , long period) // 安排指定的任务在 "指定的时间 " 开始进行 "重复" 的固定延迟执行
schedule(TimerTask task,long delay,long period)// 安排指定的任务指定的延迟后开始进行重复的固定延迟执行.
scheduleAtFixedRate(TimerTask task,Date firstTime,long period)// 安排指定的任务在指定的时间开始进行重复的固定速率执行.
scheduleAtFixedRate(TimerTask task,long delay,long period)//安排指定的任务在指定的延迟后开始进行重复的固定速率执行.
Timer.cancal()// 终止此计时器,丢弃所有当前已安排的任务。
Timer.purge()// 从此计时器的任务队列中移除所有已取消的任务。
TimerTask.cancal()// 把当前任务取消

Fixed Delay: Means that execution will start some time after the last execution started, even if it is delayed (and thus itself delayed). That is to say, the next execution time of the task is relative to the time point when the last actual execution was completed, so the execution time will continue to be delayed

Fixed frequency: means that each execution will adhere to the initial schedule, regardless of whether previous executions were delayed. That is to say, the next execution time of the task is relative to the last execution time point, so the execution time will not be delayed

Regarding these two scheduling methods, let's see how to use them:

In order to use fixed-delay scheduling, the schedule() method also has two overloads, each of which takes an additional parameter indicating the periodicity in milliseconds. Why overload twice? Because it is still possible to start the task at some point or after some delay.

As for fixed-rate scheduling, we have two scheduleAtFixedRate() methods whose period is also in milliseconds. Likewise, we have a method to start a task at a given date and time, and a method to start a task after a given delay.

One note: if a task takes longer than the execution period, it will delay the entire execution chain whether we use fixed delay or fixed rate. (The fixed rate will be executed continuously, and the fixed delay will wait for the delay before executing)

specific code

schedule(TimerTask task, Date time)

/**
 * @PROJECT_NAME: demo
 * @DESCRIPTION: 指定时间执行
 */
public class TimerDemo {
    
    
    public static void main(String[] args) {
    
    
        Calendar ca = Calendar.getInstance();
        System.out.println(ca.getTime());
        ca.set(Calendar.SECOND, ca.get(Calendar.SECOND) + 5);
        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(new Date(scheduledExecutionTime());
            }
        }, ca.getTime());
    }
}

schedule(TimerTask task,long delay)

/**
 * @PROJECT_NAME: demo
 * @DESCRIPTION: 延迟指定时间后执行
 */
public class DelayDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(new Date());
        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(new Date(scheduledExecutionTime());
            }
        }, 2000);
    }
}

schedule(TimerTask task, Date firstTime, long period)

/**
 * @PROJECT_NAME: demo
 * @DESCRIPTION: 安排指定的任务在 "指定的时间 " 开始进行 "重复" 的固定延迟执行
 */
public class FirstAndPeriodDemo {
    
    
    public static void main(String[] args) {
    
    
        Calendar ca = Calendar.getInstance();
        System.out.println(ca.getTime());
        ca.set(Calendar.SECOND, ca.get(Calendar.SECOND) + 2);
        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(new Date(scheduledExecutionTime()));
            }
        }, ca.getTime(),2000);
    }
}

The first task is delayed by 2s, and then because the thread execution time is 3s, the next task is started at the end of the task.
insert image description here

schedule(TimerTask task,long delay,long period)


/**
 * @PROJECT_NAME: demo
 * @DESCRIPTION: 安排指定的任务在“指定的延迟”后开始进行“重复”的固定延迟执行
 */
public class DelayAndPeriodDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(new Date());
        new Timer().schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(new Date(scheduledExecutionTime()));
            }
        }, 1000,2000);
    }
}

insert image description here

scheduleAtFixedRate(TimerTask task,Date firstTime,long period)

/**
 * @PROJECT_NAME: demo
 * @DESCRIPTION:
 */
public class FixAndFirstDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(new Date());
        new Timer().scheduleAtFixedRate(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(new Date(scheduledExecutionTime()));
            }
        }, 1000, 2000);
    }
}

Executed at a fixed rate.
insert image description here
However, another problem arises here. Since the Timer is internally implemented by a single thread, how does scheduleAtFixedRate output once every 2 seconds when the execution interval is 2 seconds and the actual execution time of the task is 3 seconds?

【pay attention】

This is actually a blindfold. It is important to note that the value output by the print method is generated by calling scheduledExecutionTime(), and this method is not necessarily the actual execution time of the task, but the time when the current task should be executed.
Source code understanding

Guess you like

Origin blog.csdn.net/doublepg13/article/details/128317159