多线程十 Timer
定时/计算在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)
注意点:
- firstTime晚于当前时间,计划未来
- firstTime早于当前时间,计划立即执行
- 任务依然可能被延迟
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
...
TimerTask与Timer的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的更多相关文章
- java多线程--定时器Timer的使用
定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术. Time类主要负责完成定时计划任务的功能,就是在指定 ...
- 多线程&定时器Timer&同步&线程通信&ThreadLocal
1.多线程 线程状态分为:新建状态.就绪状态.运行状态.阻塞状态.死亡状态 对象等待池的阻塞状态:运行状态执行了wait方法 对向锁池的阻塞状态:试图获得某个同步锁,已经被其他线程占用,就会放到对象的 ...
- 多线程-定时器Timer
2019-04-1218:03:32 package 多线程.定时器Timer_重要; import java.util.Timer; import java.util.TimerTask; publ ...
- 多线程 定时器 Timer TimerTask
定时器是一种特殊的多线程,使用Timer来安排一次或者重复执行某个任务 package org.zln.thread; import java.util.Date; import java.util. ...
- 多线程十之CopyOnWriteArrayList源码分析
目录 简介 类结构 源码解析 构造方法 add(E e) add(int index, E element) get(int index) remove(int index) 迭代器Iterator遍 ...
- Java 多线程--ThreadLocal Timer ExecutorService
ThreadLocal /** * ThreadLocal:每个线程自身的存储本地.局部区域 * @author xzlf * */ public class ThreadLocalTest01 { ...
- c# 中的多线程和异步
前言: 1.异步和多线程有区别吗? 答案:多线程可以说是实现异步的一种方法方法,两者的共同目的:使主线程保持对用户操作的实时响应,如点击.拖拽.输入字符等.使主程序看起来实时都保持着等待用户响应的状态 ...
- .NET中的三种Timer的区别和用法
最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗体应 ...
- .NET中的三种Timer的区别和用法(转)
最近正好做一个WEB中定期执行的程序,而.NET中有3个不同的定时器.所以正好研究研究.这3个定时器分别是: //1.实现按用户定义的时间间隔引发事件的计时器.此计时器最宜用于 Windows 窗 ...
随机推荐
- Ubuntu 18.04 美化配置
网上很多关于Ubuntu 18.04 美化的配置,但每个人遇见的问题都有些不太一样, 现将本人配置的过程整理如下 更新源为阿里云 找到Software & Updates,将源更新为阿里云的源 ...
- return之为什么能够终止函数,代码演练
''' return 有终止函数的作用,下面通过执行到return x 以后, 就结束了程序的下一步执行,所以就没有往下面走,所以终端上也就只能 看到打印结果100,看不到打印呢 ''' def se ...
- dev gridcontrol 行号
/// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...
- 《Java基础知识》Java线程的概念
按照规划,从本篇开始我们开启『并发』系列内容的总结,从本篇的线程开始,到线程池,到几种并发集合源码的分析,我们一点点来,希望你也有耐心,因为并发这块知识是你职业生涯始终绕不过的坎,任何一个项目都或多或 ...
- 【CV现状-3.0】"目标"是什么
#磨染的初心--计算机视觉的现状 [这一系列文章是关于计算机视觉的反思,希望能引起一些人的共鸣.可以随意传播,随意喷.所涉及的内容过多,将按如下内容划分章节.已经完成的会逐渐加上链接.] 缘起 三维感 ...
- vue-practice
vue-完整代码 这是一个完整的vue案例,但是接口似乎都失效了,单是代码本身还是很有参考价值的呦!~ 里面包含了:vue,vue-router,....,还是直接看json文件吧 { "n ...
- JS---DOM---总结绑定事件的区别
总结绑定事件的区别: addEventListener(); attachEvent() 相同点: 都可以为元素绑定事件 不同点: 1.方法名不一样 2.参数个数不一样addEventListen ...
- React搭建项目(全家桶)
安装React脚手架: npm install -g create-react-app 创建项目: create-react-app app app:为该项目名称 或者跳过以上两步直接使用: npx ...
- 2019年Java面试题基础系列228道(2)
21.描述一下 JVM 加载 class 文件的原理机制? JVM 中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java 中的类加载器是一个重要的 Java 运行时系统组件,它 ...
- PL/SQL Developer查詢已經執行過的SQL語句記錄 Ctrl+E
PL/SQL Developer查詢已經執行過的SQL語句記錄 最近提数比较多,没有已存在的脚本信息,就手工写呀... 一次性打开了多个提数脚本文件,结果执行完后把脚本保存好了,但是最后的整理其它脚本 ...