定时/计算在java中主要使用的是Timer对象,他的内部依然是采用多线程方式进行处理

它有四个构造方法

方法名 作用
Timer() 空参
Timer(String name) 指定名字
Timer(boolean isDaemon) 指定为守护线程
Timer(String name,boolean isDaman) 指定名字,指定为守护线程

Timer类的主要作用就是设置计划任务,但是封装任务的类确是TimerTask,TimerTask实现了Runable接口,因此我们要做的也就是重写run方法,定义我们的任务


  • 简单使用
public class demo01 extends TimerTask {
@Override
public void run() {
System.out.println("计划执行了, "+new Date());
} public static void main(String[] args) {
System.out.println("当前时间 "+ new Date()); Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,5);
Date time = calendar.getTime();
demo01 task = new demo01();
Timer timer = new Timer();
timer.schedule(task,time);
System.out.println("主线程结束了...");
}
}

程序执行完了,但是进程仍然没有被撤销,呈红色状态,那是因为每创建一个Timer对象,就是启动一条线程,并且这条线程不是守护线程,会一直执行下去


常用的几个Timer对象的API

1. 安排在指定的时间执行指定的任务,如果时间过去了,立即执行

void schedule(TimerTask task,Date time)

一个Timer对象,可以拥有多个TimerTask,而TimerTask是以队列的方法,一个一个顺序执行,这也就可能导致执行的时间和预期的时间不一样,因为前面的任务执行的时间可能比较长,那么后面的任务也就被延后了


2. 在指定的日期到达之后,按照指定的时间间隔,执行一次某任务

schedule(TimerTask task , Date firstTime,Long period)

注意点:

  1. firstTime晚于当前时间,计划未来
  2. firstTime早于当前时间,计划立即执行
  3. 任务依然可能被延迟

3, 以当前时间为准,在此时间基础上延迟指定的时间毫秒数执行一次TimerTask任务

schedule(TimerTask task, Long delay)

5 .当前的时间为参考,在此时间基础上延迟指定的毫秒数,再以某一个时间间隔,无限次执行某一任务

schedule(TimerTask task,Long delay,Long period)

6. 测试schedule&scheduleAtFixedRate几种情况

不延迟 描述
Date类型 下一次执行任务的时间,都是上一次任务开始的时间+period
Long类型 第一次任务执行的时间是任务开始的时间+delay,接下来执行任务的时间是上一次任务开始的时间+priod
延迟 描述
Date类型 下一次执行任务的时间,都是上一次任务结束的时间+period
Long类型 下一次执行任务的时间是上一次任务结束的时间+priod

7. 追赶性

举个例子什么是追赶性,假如说,程序运行到A行代码时,时间是t1,程序继续往下执行,遇到了B行代码,我们希望,B在A前10秒执行给定的任务,可是按照我们的顺序,A已经执行了,那么实现我们的要求就用到了scheduleAtFixedRate的追赶性

示例代码:

/*
* schedule的追赶性
* */
public class demo03 extends TimerTask { @Override
public void run() {
System.out.println("任务开始的时间"+new Date());
System.out.println("任务结束的时间"+new Date());
} public static void main(String[] args) {
System.out.println("现在执行的时间+"+new Date()); demo03 task = new demo03(); Calendar instance = Calendar.getInstance();
instance.set(Calendar.SECOND,instance.get((Calendar.SECOND)-10));
Date time = instance.getTime();
System.out.println("计划执行的时间"+ time);
Timer timer = new Timer();
timer.scheduleAtFixedRate(task,time,2000);
}
}

结果:

现在执行的时间+Sat Feb 16 07:17:14 CST 2019
计划执行的时间Sat Feb 16 07:17:07 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:14 CST 2019
任务结束的时间Sat Feb 16 07:17:14 CST 2019
任务开始的时间Sat Feb 16 07:17:15 CST 2019
任务结束的时间Sat Feb 16 07:17:15 CST 2019
任务开始的时间Sat Feb 16 07:17:17 CST 2019
任务结束的时间Sat Feb 16 07:17:17 CST 2019
任务开始的时间Sat Feb 16 07:17:19 CST 2019
任务结束的时间Sat Feb 16 07:17:19 CST 2019
任务开始的时间Sat Feb 16 07:17:21 CST 2019
任务结束的时间Sat Feb 16 07:17:21 CST 2019
任务开始的时间Sat Feb 16 07:17:23 CST 2019
...

TimerTaskTimer的cancel方法

  • TimerTask的cancel()自然由TimerTask对象调用,它本身是任务队列中的一个任务,作用是把自身从任务队列中进行清除
  • Timer的cancel()方法**把整个任务队列清除

Timer的cancel的注意事项

public class demo02 extends TimerTask {

    private int i;

    public demo02(int i) {
this.i = i;
} @Override
public void run() {
System.out.println("任务被第"+i+"次执行,没有被取消");
} public static void main(String[] args) {
int i=0;
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime(); while(true){
i++;
Timer timer = new Timer();
timer.schedule(new demo02(i),time);
timer.cancel();
} }

运行结果

任务被第32412次执行,没有被取消

原因是Timer类中的cancel方法,有时抢不到任务队列的锁,而让TimerTask类中的任务正常执行


参考书籍<<java多线程编程核心技术>>高洪岩著

多线程十 Timer的更多相关文章

  1. java多线程--定时器Timer的使用

    定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术. Time类主要负责完成定时计划任务的功能,就是在指定 ...

  2. 多线程&定时器Timer&同步&线程通信&ThreadLocal

    1.多线程 线程状态分为:新建状态.就绪状态.运行状态.阻塞状态.死亡状态 对象等待池的阻塞状态:运行状态执行了wait方法 对向锁池的阻塞状态:试图获得某个同步锁,已经被其他线程占用,就会放到对象的 ...

  3. 多线程-定时器Timer

    2019-04-1218:03:32 package 多线程.定时器Timer_重要; import java.util.Timer; import java.util.TimerTask; publ ...

  4. 多线程 定时器 Timer TimerTask

    定时器是一种特殊的多线程,使用Timer来安排一次或者重复执行某个任务 package org.zln.thread; import java.util.Date; import java.util. ...

  5. 多线程十之CopyOnWriteArrayList源码分析

    目录 简介 类结构 源码解析 构造方法 add(E e) add(int index, E element) get(int index) remove(int index) 迭代器Iterator遍 ...

  6. Java 多线程--ThreadLocal Timer ExecutorService

    ThreadLocal /** * ThreadLocal:每个线程自身的存储本地.局部区域 * @author xzlf * */ public class ThreadLocalTest01 { ...

  7. c# 中的多线程和异步

    前言: 1.异步和多线程有区别吗? 答案:多线程可以说是实现异步的一种方法方法,两者的共同目的:使主线程保持对用户操作的实时响应,如点击.拖拽.输入字符等.使主程序看起来实时都保持着等待用户响应的状态 ...

  8. .NET中的三种Timer的区别和用法

    最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗体应 ...

  9. .NET中的三种Timer的区别和用法(转)

      最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗 ...

随机推荐

  1. 爬虫(十):AJAX、爬取AJAX数据

    1. AJAX 1.1 什么是AJAX AJAX即“Asynchronous JavaScript And XML”(异步JavaScript和XML)可以使网页实现异步更新,就是不重新加载整个网页的 ...

  2. FCC---CSS Flexbox: Use the flex-direction Property to Make a Column

    The last two challenges used the flex-direction property set to row. This property can also create a ...

  3. Zabbix Server 3.2

    软件环境 Centos7.3 LAMP Zabbix 3.2  1. Installing repository configuration package Install the repositor ...

  4. 如何向小姐姐解释SQL和NoSQL之间的区别

    最近,在Medium上出现了一个采访问题:如何向奶奶解释SQL和NoSQL之间的区别.我认为作者使用自己的结构化家谱来比较sql和nosql之间的差异.写作非常好,但是有点尴尬.面试官没有时间听你的话 ...

  5. Centos 中使用通过docker 部署.netcore

    此前,我一直觉得,目前网络上的各种各样的技术文章.技术文档已经足够多,任何一种技术,都可以或多或少的在网络上找到教程,或者在qq群里找到前辈解答.所以,我觉得自己在博客上写文章的意义甚少.甚至觉得自己 ...

  6. ESP32的NVS使用指南

    NVS总的来说,就是非易失性存储,类似MCU EEPROM,但实际上调用ESP32这些函数,数据是存储在FLASH中的. 它的管理方式类似数据库的表,在NVS里面可以存储很多个不同的表,每个表下面有不 ...

  7. Windows Redis 安装(带视频)

    疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 疯狂创客圈 高并 ...

  8. SpringCloud Zuul2.X网关实现服务熔断降级(复制即用)

    版本: <properties> <spring-boot.version>.RELEASE</spring-boot.version> <spring-cl ...

  9. sap-abap 权限控制

    FORM AUTH_CHECK . "工厂 LOOP AT S_WERKS. AUTHORITY-CHECK OBJECT 'M_BANF_WRK' ID 'WERKS' FIELD S_W ...

  10. 5.java基础之static、类加载过程

    static修饰符 修饰属性:静态的属性不属于任何对象,全类及其对象共用,可以用类名直接调用 修饰方法:静态的方法可以直接用类名调用,和对象无关.静态方法只能访问静态成员和静态方法,非静态方法可以调用 ...