我是靠谱客的博主 单薄洋葱,这篇文章主要介绍【Java案例实践】Java定时器最全讲解(包括多线程定时任务)1.Java定时器需要用到的类:2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)3.Timer的缺点及改进方法4.使用ScheduledExecutorService替代Timer,现在分享给大家,希望可以做个参考。

在Java开发中定时器算是一个非常经典的小案例,在正式的项目中定时器也会经常使用。所以突然兴起想对定时器来一个总结分析,本人小白一个,请多多指教!

首先什么是Java定时器?
定时器相信大家都不陌生,平时使用定时器就像使用闹钟一样,我们可以在固定的时间做某件事,也可以在固定的时间段重复做某件事。在Java中为我们提供了Timer来实现定时任务,当然现在还有很多定时任务框架,比如说Spring、QuartZ、Linux Cron等等,而且性能也更加优越。但是我们想要深入的学习就必须先从最简单的开始。

1.Java定时器需要用到的类:

在JAVA中实现定时器功能要用的2个类是Timer,TimerTask
Timer类是用来履行任务的类,它接受1个TimerTask做参数
TimerTask是用来指定执行任务的类

2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)

最经常使用的是schedule,它可以以两种方式履行任务:
1、在某个时间(Data),
2、在某个固定的时间以后(int delay)。
这两种方式都可以指定任务履行的频率

schedule和scheduleAtFixedRate的区分在于,如果指定开始履行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已过去的时间也作为周期履行,而schedule不会把过去的时间算上。

案例代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.anyi.timer; import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * @description: * @author: anyi * @date: 2021-03-05 09:42 **/ public class TimerTest1 { public static void main(String[] args){ timer1(); timer2(); } /** * @Description: 设定2000毫秒后执行 */ public static void timer1() { Timer nTimer = new Timer(); nTimer.schedule(new TimerTask() { @Override public void run() { System.out.println("执行指定的任务"); System.out.println("--起床--"); } }, 2000); } /** * @Description: 延迟5000毫秒,每1000毫秒执行一次 */ public static void timer2(){ Timer nTimer = new Timer(); nTimer.schedule(new TimerTask() { @Override public void run() { System.out.println("执行指定任务"); System.out.println("--吃饭--"); } }, 5000, 1000); } //延迟5000毫秒,每1000毫秒执行一次 public static void timer3(){ Timer nTimer = new Timer(); nTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println("执行指定任务"); System.out.println("背英语单词"); } }, 5000, 1000); } /** * 设置17:56执行任务 * java.util.Timer.scheduleAtFixedRate(TimerTask task, Date firstTime, long period) */ public static void timer4(){ Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 17); calendar.set(Calendar.MINUTE, 56); calendar.set(Calendar.SECOND, 0); Date time = calendar.getTime(); Timer nTimer = new Timer(); nTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println("执行指定任务"); System.out.println("码代码"); } }, time,1000*24*60*60);// 这里设定将延时每天固定执行 } }

3.Timer的缺点及改进方法

Timer不支持并发,Timer不支持多线程,一个Timer只开启一个线程。全部挂在Timer下的任务都是单线程的,任务仅仅能串行运行。假设当中一个任务运行时间过长。会影响到其它任务的运行,然后就可能会有各种接踵而来的问题。如果重开一个Timer?难道要为全部的耗时的Task都单开一个Timer。显然是不太可能。这样就太乱了。
Timer的线程不捕获异常。TimerTask假设抛出异常,那么Timer唯一的进程就会挂掉,这样挂在Timer下的全部任务都会无法继续运行
改进方法:
为了弥补Timer的缺陷,jdk1.5中引入了并发包。这里面提供的ScheduledExecutorService。详细实现类是:ScheduledThreadPoolExecutor。ScheduledThreadPoolExecutor支持多线程。同一时候在线程中对异常进行了捕获。所以是Timer的完美替换者。

这种情况,我们只需要按照阿里规约里面给的建议。
在这里插入图片描述

多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务会自动终止运行,使用ScheduledExecutorService则没有这个问题。
————————————————
摘自:
原文链接:https://blog.csdn.net/u013636987/article/details/102671841

4.使用ScheduledExecutorService替代Timer

(1)注意事项(避坑!)
其中BasicThreadFactory类来自:org.apache.commons.lang3.concurrent.BasicThreadFactory,需要导入相应的第三方jar包,否则会报Cannot resolve symbol ‘BasicThreadFactory’
这里使用maven的方式导入:

复制代码
1
2
3
4
5
6
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.8</version> </dependency>

(2)根据规约的提示我们写一个简单的demo (JDK1.8+)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component public class ScheduledThreadPoolTaskTimer { @PostConstruct public void init(){ ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("task-timer-pool-%d").daemon(true).build()); executorService.scheduleAtFixedRate(this::performingTasks,0,1000, TimeUnit.MILLISECONDS); } public void performingTasks(){ System.out.println("Are you ok?"+System.currentTimeMillis()); } }

这里我们使用了BasicThreadFactory去创建线程,也就是采用线程池的方式。scheduleAtFixedRate方法参数如下

@param command 要执行的任务
@param initialDelay 延迟首次执行的时间
@param period 连续执行之间的时间间隔
@param unit initialDelay和period参数的时间单位
————————————————
案例代码参考来自
原文链接:https://blog.csdn.net/qq_36428889/article/details/103010460

最后

以上就是单薄洋葱最近收集整理的关于【Java案例实践】Java定时器最全讲解(包括多线程定时任务)1.Java定时器需要用到的类:2.Timer有两种履行任务的模式(schedule、scheduleAtFixedRate)3.Timer的缺点及改进方法4.使用ScheduledExecutorService替代Timer的全部内容,更多相关【Java案例实践】Java定时器最全讲解(包括多线程定时任务)1.Java定时器需要用到内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部