多线程十 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 窗 ...
随机推荐
- springcloud-微服务架构基础
一 前言 学习微服务要从基础的架构学起,首先你要有个微服务的概念才能学习对吧!!如果你都不知道啥是微服务,就一头扎进去学习,你自己也觉得自己也学不会对吧.本篇文章主要让大家快速了解基础的架构分格,以便 ...
- LeetCode刷题总结-双指针、位运算和分治法篇
本文总结LeetCode上有关双指针.位运算和分治法的算法题,推荐刷题总数14道.具体考点分析如下图: 一.双指针 1.字符串和数组问题 题号:424. 替换后的最长重复字符,难度中等 题号:828. ...
- Linux下搭建HttpRunnerManager接口测试平台
前言 之前在学习HttpRunner时,我们都是把用例写在 YAML/JSON 中进行维护,使用起来也很方便.其实,现在有不少大佬都喜欢开发自动化测试平台,比如我们今天要搭建的HttpRunnerMa ...
- 升鲜宝V2.0_生鲜配送管理系统_杭州生鲜配送行业,升鲜宝使用教程 客户管理 第二章
1.新增客户 (1)新增客户有两种方式,单个添加和批量添加,客户的结构可以是独立的,也可以是父子结构(比如杭州升鲜宝科技有限公司下有西湖区部门,滨江区部门,余杭区部门等多个分部,就可以建立父子结构,这 ...
- Linux Pptpd
准备环境 1 主机ip:192.168.0.107 2 VPN服务器: ens32:192.168.0.102 ens33:127.16.1.10 软件安装 [root@localhost ~]# y ...
- Leetcode题解 - DFS部分简单题目代码+思路(113、114、116、117、1020、494、576、688)
这次接触到记忆化DFS,不过还需要多加练习 113. 路径总和 II - (根到叶子结点相关信息记录) """ 思路: 本题 = 根到叶子结点的路径记录 + 根到叶子结点 ...
- Linux命令学习-cat命令
Linux中,cat命令的全称是concatenate,主要用于显示文件内容. 查看centos系统版本 cat /etc/centos-release 查看文件 gogs.log 的内容 cat g ...
- bbbbbb
Blazor 机制初探以及什么是前后端分离,还不赶紧上车? 标签: Blazor .Net 上一篇文章我发了一个 BlazAdmin 的尝鲜版,这一次主要聊聊 Blazor 是如何做到用 C# 来写前 ...
- 通过Ajax的访问zuul的跨域问题解决方案
刚开始在使用jqueryajax跨域请求zuul网关时,在后台发现一直拿不到前台请求的json数据,而前台也一直拿不到后台的响应数据.打开浏览器调试程序发现,本身ajax的POST请求统一都变成了op ...
- WPF炫酷UI及动画
偶然看见了一张图,感觉挺好看的,花了点时间将他转化成了我代码仓库的一部分.虽然不难但也费时间.其中除了背景是百度的一张底图,其他所有内容均通过WPF的Path.Line.TextBlock.Borde ...