一步一步学多线程-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检查脚本,实现一次操作得到所有巡检结果. ...
随机推荐
- Image和字节数组互转
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; ...
- Apollo框架试玩
2017年7月5日,百度举行了AI开发者大会,在会上发布了Apollo项目,并进行了演示,该项目在Github上已经能够被访问.出于一个程序员的好奇,昨天试玩了一把,确实不错. http://apol ...
- peoplesoft function PSTREENODE 通过 deptid 获得部门树 一级部门 名称
create or replace function ht_gettopdeptNAME(deptid in varchar) return varchar2 is r ); c int; m ); ...
- 什么是Hadoop
配上官方介绍 What Is Apache Hadoop? The Apache™ Hadoop® project develops open-source software for relia ...
- 角点检测和匹配——Harris算子
一.基本概念 角点corner:可以将角点看做两个边缘的交叉处,在两个方向上都有较大的变化.具体可由下图中分辨出来: 兴趣点interest point:兴趣点是图像中能够较鲁棒的检测出来的点,它不仅 ...
- UGUI射线检测
1.Graphic Raycaster 主要用于UI上的射线检测,挂有这个组件的物体,必须要挂上Canvas这个组件(当挂上Graphic Raycaster时Canvas也会自动挂上). Ignor ...
- Android事件分发理解
Android事件分发机制是个难点和重点,结合下各家,写点自己的理解.. 首先抛出一个小问题,写一个button的点击事件 button.setOnClickListener(new OnClickL ...
- Oozie时出现Exception in thread "main" java.lang.UnsupportedClassVersionError: com/mysql/jdbc/Driver : Unsupported major.minor version 52.0?
不多说,直接上干货! 问题详情 [hadoop@bigdatamaster oozie--cdh5.5.4]$ bin/ooziedb.sh create -sqlfile oozie.sql -ru ...
- 51nod_1384:全排列(STL)
题目链接 记住next_permutation函数的用法,另外string在这里比char[]慢好多啊.. //#include<bits/stdc++.h> //using namesp ...
- luogu P2756 飞行员配对方案问题
题目链接:P2756 飞行员配对方案问题 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另 ...