定时/计算在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. Ubuntu 18.04 美化配置

    网上很多关于Ubuntu 18.04 美化的配置,但每个人遇见的问题都有些不太一样, 现将本人配置的过程整理如下 更新源为阿里云 找到Software & Updates,将源更新为阿里云的源 ...

  2. return之为什么能够终止函数,代码演练

    ''' return 有终止函数的作用,下面通过执行到return x 以后, 就结束了程序的下一步执行,所以就没有往下面走,所以终端上也就只能 看到打印结果100,看不到打印呢 ''' def se ...

  3. dev gridcontrol 行号

    /// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...

  4. 《Java基础知识》Java线程的概念

    按照规划,从本篇开始我们开启『并发』系列内容的总结,从本篇的线程开始,到线程池,到几种并发集合源码的分析,我们一点点来,希望你也有耐心,因为并发这块知识是你职业生涯始终绕不过的坎,任何一个项目都或多或 ...

  5. 【CV现状-3.0】"目标"是什么

    #磨染的初心--计算机视觉的现状 [这一系列文章是关于计算机视觉的反思,希望能引起一些人的共鸣.可以随意传播,随意喷.所涉及的内容过多,将按如下内容划分章节.已经完成的会逐渐加上链接.] 缘起 三维感 ...

  6. vue-practice

    vue-完整代码 这是一个完整的vue案例,但是接口似乎都失效了,单是代码本身还是很有参考价值的呦!~ 里面包含了:vue,vue-router,....,还是直接看json文件吧 { "n ...

  7. JS---DOM---总结绑定事件的区别

    总结绑定事件的区别: addEventListener(); attachEvent()   相同点: 都可以为元素绑定事件 不同点: 1.方法名不一样 2.参数个数不一样addEventListen ...

  8. React搭建项目(全家桶)

    安装React脚手架: npm install -g create-react-app 创建项目: create-react-app app app:为该项目名称 或者跳过以上两步直接使用: npx ...

  9. 2019年Java面试题基础系列228道(2)

    21.描述一下 JVM 加载 class 文件的原理机制? JVM 中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java 中的类加载器是一个重要的 Java 运行时系统组件,它 ...

  10. PL/SQL Developer查詢已經執行過的SQL語句記錄 Ctrl+E

    PL/SQL Developer查詢已經執行過的SQL語句記錄 最近提数比较多,没有已存在的脚本信息,就手工写呀... 一次性打开了多个提数脚本文件,结果执行完后把脚本保存好了,但是最后的整理其它脚本 ...