一步一步学多线程-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检查脚本,实现一次操作得到所有巡检结果. ...
随机推荐
- centos中NAT模式下静态IP连接外网
使用linux虚拟机时,通常会用到yum命令来安装软件,然而这个命令需要连外网下载软件,用maven下载jar包也需要外网.虚拟机在内网可以互相ping通,然而ping不了外网,于是通过试验,终于找到 ...
- Java 泛型在实际开发中的应用
java泛型是对Java语言的类型系统的一种扩展,泛型的本质就是将所操作的数据类型参数化.下面我会由浅入深地介绍Java的泛型. 一:泛型出现的背景 在java代码里,你会经常发现类似下边的代码: p ...
- Java自学手记——泛型
泛型在集合中的应用 泛型在集合经常能看到,有两个好处:1.把运行时出现 的问题提前至了编译时:2.避免了无谓的强制类型转换. 用法:两边泛型的类型必须相同,可允许一边不写,只是为了兼容性,并不推荐. ...
- 原生js简单实现双向数据绑定原理
根据对象的访问器属性去监听对象属性的变化,访问器属性不能直接在对象中设置,而必须通过 defineProperty() 方法单独定义. 访问器属性的"值"比较特殊,读取或设置访问器 ...
- java基础06 IO流
IO用于在设备间进行数据传输的操作. Java IO流类图结构: IO流分类 字节流: InputStream FileInputStream BufferedInputStream Output ...
- CSS预编译与PostCSS以及Webpack构建CSS综合方案
CSS全称Cascading Style Sheets(层叠样式表),用来为HTML添加样式,本质上是一种标记类语言.CSS前期发展非常迅速,1994年哈肯·维姆·莱首次提出CSS,1996年12月W ...
- python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性
先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,. __getattr__:当在类中找不到attribute的时候 ...
- 【转载】 ISO14229系列之二:诊断指令格式和相关概念
转载链接:http://www.cnblogs.com/autogeek/p/4458658.html 1. 简单的通信机制 其实诊断通信的机制很简单,可以类比client-server通信方式,即客 ...
- JavaScript-DOM编程的一些常用属性
一.Document常见属性 document.title // 设置文档标题等价于HTML的title标签 document.bgColor // 设置页面背景色 document.fgColor ...
- maven项目打包发布时跳过测试
mvn命令: mvn clean install -Dmaven.test.skip=true eclipse build... 命令: clean install -Dmaven.test.skip ...