一步一步学多线程-Timer
在执行定时任务的时候可以用Timer来实现,现在小编对学到的进行一次总结,先来看一个demo
1 public class TimerTest {
2
3 public static void main(String[] args) throws ParseException {
4 Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
5 new Timer().schedule(new TimerTask() {
6 @Override
7 public void run() {
8 System.out.println(new Date().getSeconds()+" 执行");
9 }
10 }, date);
11 }
12 }
这段代码的意思是,先建一个Timer,Timer开始执行的时间是” 2017-08-17 11:18:00”。
Timer重复执行
上述代码Timer只会执行一次,如果我们想让定时任务每隔一段时间就执行呢?此时可以用Timer提供的schedule方法的另一个重载 public void schedule(TimerTask task, long delay, long period)。意思是Timer在delay的时候开始执行,每隔period时间长度执行一次。
1 public class TimerTest {
2
3 public static void main(String[] args) throws ParseException {
4 Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
5 new Timer().schedule(new TimerTask() {
6 @Override
7 public void run() {
8 System.out.println(new Date().getSeconds()+" 执行");
9 }
10 }, date,1000);
11 }
12 }
执行结果
37 执行
38 执行
39 执行
40 执行
……
Timer执行延时
在执行TimerTask的时候可能会出现线程执行时间过长的情况,超过了Timer的等待时间。此时会是什么情况呢?
public class TimerTest {
public static void main(String[] args) throws ParseException {
Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:18:00");
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println(new Date().getSeconds()+" 开始执行");
try {
Thread.sleep(2000);
System.out.println(new Date().getSeconds()+" 执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, date,1000);
}
}
看执行结果
0 开始执行
2 执行结束
2 开始执行
4 执行结束
4 开始执行
6 执行结束
6 开始执行
8 执行结束
8 开始执行
scheduleAtFixedRate
使用schedule方法执行Timer任务,如果开始的时间是在当前时间之前,Timer并不会对之前没有执行的任务进行补充执行。也就是延时之后,那么Timer就从当前时间开始接着按照间隔时间执行。但是有时候我们的需求更加关注的执行的频率,需要把因为延时而导致没有执行的任务补充回来,此时就需要用到scheduleAtFiexdRate。
public class TimerTest {
public static void main(String[] args) throws ParseException {
final Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:52:00");
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(date);
System.out.println(new Date().getSeconds() + " 开始执行");
System.out.println("执行了");
System.out.println(new Date().getSeconds() + " 执行结束");
}
}, date, 10000);
}
}
执行结果
39 开始执行
执行了
39 执行结束
Thu Aug 17 11:52:00 CST 2017
39 开始执行
执行了
39 执行结束
Thu Aug 17 11:52:00 CST 2017
40 开始执行
执行了
40 执行结束
通过执行结果可以看出来,scheduleAtFixedRate上来就先将缺失的执行补上,然后再开始按照间隔时间一次一次执行。
将Timer设置成守护线程
public class TimerTest {
public static void main(String[] args) throws ParseException {
final Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2017-08-17 11:52:00");
Timer timer=new Timer();
TimerTask timerTask= new TimerTask() {
@Override
public void run() {
System.out.println(date);
System.out.println(new Date().getSeconds() + " 开始执行");
System.out.println("执行了");
System.out.println(new Date().getSeconds() + " 执行结束");
}
};
timer.schedule(timerTask, date);
}
}
在执行完代码之后,程序仍然在运行。看Timer.class的源代码可以发现Timer是创建了一个新的线程,而持续跟踪代码发现,新的线程进行了一个while(true)循环,再其中进入了等待状态。
public Timer(String name) {
thread.setName(name);
thread.start();
}
解决办法
将Timer设置成守护线程,Timer有个构造函数。
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}
所以我们在将new Timer()改为new Timer(true)即可。
TimerTask和Timer的cancel方法
TimerTask的cancel方法是关闭这个任务,Timer的cancel方法是关闭整个Timer。
Timer的执行实际上是启动了一个线程然后,线程中维护了一个队列,然后把TimerTask放入队列中。TimerTask的cancel方法就是将自身从任务队列中移除。Timer的cancel方法,是将队列中的任务全部清空。
一步一步学多线程-Timer的更多相关文章
- 【Linux】一步一步学Linux——Linux发展史(01)
目录 00. 目录 01. Linux概述 02. Linux简史 03. Linux主要特性 04. Linux之父 05. Linux相关术语 06. Linux其它 07. Linux应用领域 ...
- 一步一步学ROP之linux_x64篇
一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...
- 一步一步学ROP之linux_x86篇
一步一步学ROP之linux_x86篇 作者:蒸米@阿里聚安全 一.序 ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过 ...
- (转载)一步一步学Linq to sql系列文章
现在Linq to sql的资料还不是很多,本人水平有限,如果有错或者误导请指出,谢谢. 一步一步学Linq to sql(一):预备知识 一步一步学Linq to sql(二):DataContex ...
- 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计
本帖最后由 xinxincaijq 于 2013-1-9 10:27 编辑 一步一步学ZedBoard & Zynq(四):基于AXI Lite 总线的从设备IP设计 转自博客:http:// ...
- 一步一步学android控件(之十五) —— DegitalClock & AnalogClock
原本计划DigitalClock和AnalogClock单独各一篇来写,但是想想,两个控件的作用都一样,就和在一起写一篇了. DegitalClock和AnalogClock控件主要用于显示当前时间信 ...
- 一步一步学Remoting系列文章
转自:http://www.cnblogs.com/lovecherry/archive/2005/05/24/161437.html (原创)一步一步学Remoting之一:从简单开始(原创)一步一 ...
- 一步一步学android控件(之十六)—— CheckBox
根据使用场景不同,有时候使用系统默认的CheckBox样式就可以了,但是有时候就需要自定义CheckBox的样式.今天主要学习如何自定义CheckBox样式.在CheckBox状态改变时有时需要做一些 ...
- 一步一步学Python(2) 连接多台主机执行脚本
最近在客户现场,每日都需要巡检大量主机系统的备库信息.如果一台台执行,时间浪费的就太冤枉了. 参考同事之前写的一个python脚本,配合各主机上写好的shell检查脚本,实现一次操作得到所有巡检结果. ...
随机推荐
- winform .net2.0的程序如何运行于.net 4.x
约束 最近有一个winform项目,要求: (1)程序能够运行在winxp, win7, win8, win10中 (2)安装尽可能简单,尽量不要安装.net framework.即使要安装也要尽可以 ...
- CSS 从入门到忘记
CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离. 一. css的三种引入方式 二. css的选择器(Select ...
- 我的学习之路_第二十八章_JQuery 和validator插件
jQuery 利用jQuery进行遍历 js原生: for(var i=0;i>?;i++){ } jQuery: 方式一: 想要遍历的jQuery对象.each(function(index, ...
- 关于JAVA正则匹配空白字符的问题
今天遇到一个字符串,怎么匹配空格都不成功!!! 我把空格复制到test.properties文件 显示“\u3000” ,这是什么? 这是全角空格!!! 查了一下 \s 不支持全角 1.& ...
- Android服务端的设计
1.创建自己的MyServletContextListener.java: package yybwb; import java.net.ServerSocket; import javax.serv ...
- 18-EasyNetQ:发生错误的情况
这一篇文章让我们看看在消息系统中可能发生的各种错误的情况下,看下EasyNetQ如何处理它们. 订阅服务挂了 当你写了一个windows 服务,用来订阅一个NewCustomerMessage消息. ...
- WNMP(Windows + Nginx + PHP + MySQL) 安装
最近在开发一个新的项目,环境用的是: Nginx1.10.3 下载地址: http://nginx.org/en/download.html 下载windows版本包 PHP 7.1.1 下载地 ...
- MySQL主从复制的实现过程
一.什么是主从复制 将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做):从而使得从数据库的数据与主数据库保持一致. 二.主从复制的作用 1. ...
- 采用HTML5之"data-"机制自由提供数据
周末总是过得很快,又到了跟代码亲密接触的日子,我在北京向各位问好,今天我分享一点关于前端的东西,HTML5之标签"data-*"自定义属性的值传递. 在过去学习JavaScript ...
- OI内的排列与组合(简单版)
§1基本原理 △让我们来看下面问题: 从甲地到乙地,可以乘火车,也可以乘汽车,还可以乘轮船.一天中,火车有4班,汽车有2班,轮船有3班.那么,一天中乘坐这些交通工具从甲地到乙地共有多少种不同走法?△分 ...