一步一步学多线程-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检查脚本,实现一次操作得到所有巡检结果. ...
随机推荐
- TSC打印机使用教程终极版
最近公司做一个资产采集的项目,之前做过此类项目,不过没有整理资料,借这次机会写一下,做个记录. 本教程使用的打印机型号:TSC TTP-244 Plus 官方文档 一.TSC打印机安装 1.机 ...
- NewsDao
package com.pb.news.dao; import java.util.Date;import java.util.List; import com.pb.news.entity.News ...
- 把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理
把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理 1 编译安装httpd 把httpd编译安装在/app/httpd/目录下. 2 在/etc/rc.d/init ...
- JavaScript中闭包实现的私有属性的getter()和setter()方法
注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- window10(64bit)+VS2010编译ACE_TAO源码库
1.下载 ACE+TAO下载地址:http://download.dre.vanderbilt.edu/previous_versions/ VS2010下载地址:https://pan.baidu. ...
- 玩玩微信公众号Java版之准备
微信自2013年流行起来,现在的发展已经超过了我们的想象,那么对应的公众平台,小程序等都是让人眼前一亮的东西,这里来学习一下微信工作号的对接,实现为Java,希望大家一起学习! 这里大概描述一下所 ...
- angularjs-1.3代码学习 模块
花了点时间,阅读了下angularjs的源码.本次先从模块化开始. angular可以通过module的api来实现前端代码的模块化管理.跟define类似.但不具备异步加载脚本的功能.先从最基本的m ...
- poj_3258:River Hopscotch(二分)
题目链接 L为N+2块石子中最右边石子位置,0最左,M为可移除块数,求移除后相邻石子可达到的最大距离. #include<iostream> #include<cstdio> ...
- Effective Objective-C 2.0 Tips 总结 Chapter 3 & Chapter 4
Chapter 3 接口与 API 设计 Tips 15 使用前缀避免明明空间冲突 Objective-C 没有命名空间,所以我们在起名时要设法避免命名冲突 避免命名冲突的方法就是使用前缀 应用中的所 ...
- 让初学者快速了解Git
Git工作原理 为了更好的学习Git,我们们必须了解Git管理我们文件的3种状态,分别是已提交(committed).已修改(modified)和已暂存(staged),由此引入 Git 项目的三个工 ...