首页 > 编程语言 >Java_Timer

Java_Timer

时间:2023-06-08 22:36:47浏览次数:64  
标签:######## Java void period Timer TimerTask 执行



 

Java_Timer

 

ava.util.Timer是一个实用工具类,该类用来调度一个线程,使它可以在将来某一时刻执行。 Java的Timer类可以调度一个任务运行一次,或定期运行。

 

java.util.TimerTask是一个抽象类,它实现了Runnable接口。我们需要扩展该类以便创建自己的TimerTask,这个TimerTask内部使用java Timer类,可以被调度。

 

Timer类是线程安全的,多进程不需要外部同步机制就可以共享同一个Timer对象。Timer类使用java.util.TaskQueue在指定时间间隔添加任务,在任何时刻只能有一个线程执行TimerTask。例如,创建一个每10秒运行的Timer,但单个线程的执行时间花费20秒,Timer对象将持续将任务添加到队列,一旦有任务结束,它就会通知队列,并且另外一个线程将启动执行。

 

Timer类使用对象的wait和notify方法来调度任务。

 

一、调用方法:

 

(1)void java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后执行任务

(2)void java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务

(3)void java.util.Timer.schedule(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。

(4)void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。

(5)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。

(6)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。

void java.util.Timer.cancel():终止该Timer

boolean java.util.TimerTask.cancel():终止该TimerTask

可以为每个Timer指定多个TimerTask

虽然可通过void java.util.Timer.schedule(TimerTask task, Date firstTime, long period)方法完成“例如:每天上午10点执行一次”的业务,但该实现是基于进行一天(1000 * 60 * 60 * 24毫秒)进行延迟的机制实现的,并不是指定某个具体时间进行执行的。

对于该种需求,可通过Quartz来进行实现

 

二、方法名称schedule()和scheduleAtFixedRate()两者的区别

当需要根据period区间时间循环多次调用任务的时候,会存在两种不同的策略,两种方法提供了不同的策略。

调用方法(1)、(2)只是单次执行,不存在多次调用任务的情况,所以没有提供scheduleAtFixedRate方法的调用方式。

<1>schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次

<2>scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果某一次调用时间大于period,下一次就会尽量小于period,以保障频率接近于period

 

 

三、示例

 

(1)
 
/** 
 * 第一种方法:设定多长时间(毫秒)后执行任务 
 */  
public static void timer1() {  
    final StopWatch watch = new StopWatch();  
    watch.start();  
    Timer timer = new Timer();  
    /* void java.util.Timer.schedule(TimerTask task, long delay) */  
    timer.schedule(new TimerTask() {  
        public void run() {  
            watch.stop();  
            System.out.println("-------任务执行--------");  
            System.out.println(watch.getTime());  
        }  
    }, 2000);// delay=2000毫秒 后执行该任务  
}

(2)

 

/** 
 * 第二种方法:设定某个时间执行任务 
 */  
public static void timer2() {  
    Calendar calendar = new GregorianCalendar();  
    calendar.add(Calendar.MINUTE, 1);  
    calendar.set(Calendar.SECOND, 0); // 一分钟后执行  
    Timer timer = new Timer();  
    /* void java.util.Timer.schedule(TimerTask task, Date time) */  
    timer.schedule(new TimerTask() {  
        @Override  
        public void run() {  
            System.out.println("-------任务执行--------");  
        }  
    }, calendar.getTime());  
}

(3)

 

/** 
 * 第三种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行 
 */  
public static void timer3() {  
    Timer timer = new Timer();  
    final StopWatch watch = new StopWatch();  
    watch.start();  
    System.out.println(Thread.currentThread().getName());  
    /* 
     * void java.util.Timer.schedule(TimerTask task, long delay, long 
     * period) 
     */  
    timer.schedule(new TimerTask() {  
        public void run() {  
            /* 子线程进行任务的执行 */  
            System.out.println(Thread.currentThread().getName());  
            System.out.println("-------设定要指定任务--------");  
            watch.suspend();  
            System.out.println(watch.getTime());  
            watch.reset();  
            watch.start();  
        }  
    }, 1000, 1000);  
}

(4)

 

/** 
 * 固定延迟peroid时间后执行;peroid时间不是以任务执行完的时间为计算起点(某次任务执行完成后,经过peroid时间后再次调用[不是这样的])。 
 * 而是每隔peroid时间调用任务一次。当任务执行的时间小于peroid时间,可以保证每隔peroid时间调用一次。 
 * 当任务的执行时间大于peroid时间时,从现象上看:任务一执行完,就会立刻进入下一次任务的执行 
 */  
public static void timer3a() {  
    Timer timer = new Timer();  
    final StopWatch watch = new StopWatch();  
    watch.start();  
    timer.schedule(new TimerTask() {  
        Integer i = 1;  
        public void run() {  
            System.out.println(watch.getTime());  
            System.out.println("########第" + i + "次执行开始########");  
            try {  
                Thread.sleep(400);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println("########第" + i + "次执行结束########");  
            i++;  
            watch.reset();  
            watch.start();  
        }  
    }, 1000, 500);  
}

period:500毫秒;每次任务执行时间400毫秒;所以每次任务执行完成后到下一次任务调用开始的时间趋近于100毫秒

 

打印日志信息:

 

1000  

########第1次执行开始########  

########第1次执行结束########  

109  

########第2次执行开始########  

########第2次执行结束########  

93  

########第3次执行开始########  

########第3次执行结束########  

93  

########第4次执行开始########  

########第4次执行结束########  

93  

########第5次执行开始########  

########第5次执行结束########  

93  

########第6次执行开始########  

########第6次执行结束########  

93  

########第7次执行开始########  

########第7次执行结束########  

93  

########第8次执行开始########  

当将Thread.sleep(400);修改为Thread.sleep(600)时:

打印日志信息:

 

 

1000  

########第1次执行开始########  

########第1次执行结束########  

0  

########第2次执行开始########  

########第2次执行结束########  

0  

########第3次执行开始########  

########第3次执行结束########  

0  

########第4次执行开始########  

########第4次执行结束########  

0  

########第5次执行开始########  

 

 

public class MyTimerTask extends TimerTask {
 
@Override
public void run() {
System.out.println("Timer task started at:"+new Date());
System.out.println("do something...");
        System.out.println("Timer task finished at:"+new Date());
 
}
 
public static void main(String[] args) {
TimerTask timerTask = new MyTimerTask();
        Timer timer = new Timer();
        timer.schedule(timerTask, 0, 2000);
}
}

 

(5)

 

/** 
 * 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行 
 * 每天中午12点都执行一次 
 */  
public static void timer4() {  
    Calendar calendar = Calendar.getInstance();  
    calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时  
    calendar.set(Calendar.MINUTE, 0); // 控制分  
    calendar.set(Calendar.SECOND, 0); // 控制秒  
  
    Date time = calendar.getTime(); // 得出执行任务的时间,此处为今天的12:00:00  
  
    Timer timer = new Timer();  
    /* void java.util.Timer.schedule(TimerTask task, Date firstTime, long period) */  
    timer.schedule(new TimerTask() {  
        public void run() {  
            System.out.println("-------设定要指定任务--------");  
        }  
    }, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行  
}

(6)

 

/** 
 * 第五种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。 
 * timer.schedule和timer.scheduleAtFixedRate的区别: 
 * (1)schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次 
 * (2)scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果某一次调用时间大于period,下一次就会尽量小于period,以保障频率接近于period 
 */  
public static void timer5() {  
    Timer timer = new Timer();  
    /* void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period) */  
    timer.scheduleAtFixedRate(new TimerTask() {  
        public void run() {  
            System.out.println("-------设定要指定任务--------");  
        }  
    }, 1000, 500);  
}

标签:########,Java,void,period,Timer,TimerTask,执行
From: https://blog.51cto.com/u_16070335/6443798

相关文章

  • 02-前端-javaScript
    文章目录JavaScript1,JavaScript简介2,JavaScript引入方式2.1内部脚本2.2外部脚本3,JavaScript基础语法3.1书写语法3.2输出语句3.3变量3.3.1全局变量var3.3.2局部变量let3.3.3常量const3.4数据类型3.5运算符3.5.1\==和===区别▲3.5.2类型转换3.6流程控制语句3.6.1if......
  • javaWeb核心02-Request&Response -(乱码处理、字符流、字节流、虚拟目录、请求转发、重
    文章目录Request&Response1,Request和Response的概述2,Request对象2.1Request继承体系2.2Request获取请求数据2.2.1获取请求行数据2.2.2获取请求头数据2.2.3获取请求体数据2.2.4获取请求参数的通用方式基于上述理论,request对象为我们提供了如下方法:★代码演示2.3IDEA快速创......
  • Java数据类型、数组
    Java数据类型基本数据类型(8种)byte\short\int\long\;float\double;char\boolean引用数据类型类、数组、接口、枚举、注解、记录一维数组packagecom.study.onearray;publicclassOneArrayTest01{//快捷方式:psvm+回车,快速生成main方法......
  • 讲真,这三道Java入门级面试题,你也不一定能搞定
    下面是一道入门级面试题,这道题基本上都是问初级的小伙伴比较多,但如果你是中级,或者高级。我觉得未必都能回答上来。说说Java语言有哪些特点尽量答出以下几个关键词:1)简单易学。Java有丰富的类库,能够通过静态方法封装,降低API的学习成本,提高工作效率。2)面向对象。这个也是Java最重要的......
  • 给小白讲java中两大怪物,附带面试题!
    类介绍Java程序是由若干个类组成的,类也是面向对象编程思想的具体实现。以下为类的定义:publicclassUser{//私有属性privateLonguserId;privateStringname;privateIntegerage;//构造方法publicUser(){}//有残构造方法publ......
  • 如何吃透一个Java项目?
    现在Austin的文档我觉得还是比较全的,但到了看代码的时候,可能有的同学就不知道应该怎么看,有想知道模块之间的调用链路,有想一点一点把细节给全看了。这时候就很可能在项目里犯迷糊了,绕不出不来了。Java开源项目消息推送平台......
  • Java 的 8 种异步实现方式
    异步的八种实现方式线程ThreadFuture异步框架CompletableFutureSpring注解@AsyncSpringApplicationEvent事件消息队列第三方异步框架,比如Hutool的ThreadUtilGuava异步1.线程异步public class AsyncThread extends Thread {    @Override    public vo......
  • Java反射机制详解上篇
    1反射机制是什么反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。在面向对象的世界里,万事万物皆对象.在java语言里,静态的成员,普......
  • Java多态综合案例(包含接口,接口实现类)
    首先定义一个接口名为USB其次定义两个实现类分别名为KeyBorad和Mouse此时就可以使用多态了,因为实现类和接口某种意义上来说是继承关系。USBu=newKeyborad();USBu2 =newMouse();因为键盘和鼠标都具有插拔功能,所以为了方便,把这两个功能写入接口,然后实现类重写。pac......
  • 一个Java对象到底占用多大内存?
    一个Java对象到底占用多大内存? 最近在读《深入理解Java虚拟机》,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存?在网上搜到了一篇博客讲的非常好:http://yueyemaitian.iteye.com/blog/2033046,里面提供的......