精华内容
下载资源
问答
  • java 定时任务假死 定时任务阻塞 线程池消失
    2021-11-15 18:23:29

    问题现象:

            现象1.开启定时任务线程池,线程池貌似消失了,定时任务突然中断,既不执行也不报错

            现象2:跟换定时任务实现方式,使用@Scheduled,同意的现象依然出现了,定时任务跑到一定频率突然不动

    解决思路:

            1.程序未抛出异常,某个时期却突然不在执行,怀疑线程阻塞了

            2.查询jvm线程状态(jstack java进程ID >threadDump.log)将dump日志下载分析,发现该线程期处于runnable 状态,其他任务一直waiting,可以看出应该是http请求导致的

    "scheduling-1" #62 prio=5 os_prio=0 tid=0x00007f36a6fc2000 nid=0x813e runnable [0x00007f3651125000]
       java.lang.Thread.State: RUNNABLE
    	at java.net.SocketInputStream.socketRead0(Native Method)
    	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    	at java.net.SocketInputStream.read(SocketInputStream.java:171)
    	at java.net.SocketInputStream.read(SocketInputStream.java:141)
    	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    	at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:593)
    	at sun.security.ssl.InputRecord.read(InputRecord.java:532)
    	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:990)
    	- locked <0x00000006a6bb48d8> (a java.lang.Object)
    	at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:948)
    	at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
    	- locked <0x00000006a6bb4f38> (a sun.security.ssl.AppInputStream)
    	at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
    	at org.apache.http.impl.io.SessionInputBufferImpl.read(SessionInputBufferImpl.java:197)
    	at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:188)
    	at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135)
    	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    	- locked <0x00000006a6cab1e0> (a java.io.InputStreamReader)
    	at java.io.InputStreamReader.read(InputStreamReader.java:184)
    	at java.io.Reader.read(Reader.java:140)
    	at org.apache.http.util.EntityUtils.toString(EntityUtils.java:227)
    	at org.apache.http.util.EntityUtils.toString(EntityUtils.java:308)
    	at com.coco.util.HttpUtil.sendPost(HttpUtil.java:40)

            3.查询资料,httpclient有一个这样的坑,必须配置http超时时间,否则请求未响应,会导致read一直处于阻塞状态,会导致程序假死

            4.配置httpclient超时时间,问题解决,代码如下

    // 设置超时时间-务必设置,否则导致程序阻塞或线程假死
            int MAX_SOKET_TIMEOUT = 10000;
            int MAX_CONNECTION_TIMEOUT = 8000;
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(MAX_SOKET_TIMEOUT).setConnectTimeout(MAX_CONNECTION_TIMEOUT).build();
    
            CloseableHttpClient clientExecutor = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();

            5.思考扩展,导致假死的状态不只这一种,有可能是io、有可能是死循环(递归死循环等)、有可能是互斥锁,等等,都可以通过分析thread dump文件来得到线索

    更多相关内容
  • 主要介绍了Quartz实现JAVA定时任务的动态配置的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 自留demo,java定时任务quartz的基本实现,对应博客https://blog.csdn.net/jing12062011/article/details/82758536
  • 可以通过少量修改直接融入到已有的java项目,有维护定时器的界面,包括新增修改删除,立即执行,暂停,恢复等功能,省去了项目中大量配置定时器的繁琐,而且便于维护
  • JAVA定时任务

    2019-03-28 01:04:54
    NULL 博文链接:https://lyjiao.iteye.com/blog/1196320
  • 主要介绍了java定时任务框架elasticjob详解,Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架。该项目基于成熟的开源产品Quartz和Zookeeper及其客户端Curator进行二次开发。,需要的朋友可以...
  • java定时任务

    2018-10-23 08:45:35
    java代码实现的定时任务
  • java定时任务,每天定时执行任务,每天到这个时间点都会执行
  • java 定时任务及jar包

    2017-07-20 10:22:03
    定时启动任务 或者项目启动时启动
  • java 定时任务

    2017-09-12 14:24:21
    基于springboot+mybatis实现的一个定时任务项目, 直接可以使用,里面有例子,mvc分层,可以进行二次开发。
  • java定时任务JOB任务设置java定时任务JOB任务设置java定时任务JOB任务设置
  • java定时任务,每天定时执行任务,包括这个例子的全部代码。
  • Java定时任务详解

    2020-08-27 05:33:57
    定时任务在项目中经常会使用到,本文主要根据博主自己使用定时的经验分如下几点介绍定时任务:1、Quartz定时任务简介及Spring配置Quartz定时任务;2、SchedulerFactory对定时任务进行增删改查
  • 本篇文章主要介绍了利用java Timer类实现定时执行任务的功能,具有一定的参考价值,有需要的可以了解一下。
  • Java定时任务文档看

    2019-03-26 14:43:39
    文档里面是实现的逻辑代码可以看看。。
  • Java定时任务的三种实现方式

    万次阅读 2021-03-22 17:52:09
    前言现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务的定时...java 系统中主要有三种方式来实现定时任务:Timer和TimerTaskScheduledExecutorService三方框架 Quar...

    前言

    现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务的定时调度与执行也是对程序的基本要求了。

    很多业务需求的实现都离不开定时任务,例如,每月一号,移动将清空你上月未用完流量,重置套餐流量,以及备忘录提醒、闹钟等功能。

    java 系统中主要有三种方式来实现定时任务:

    Timer和TimerTask

    ScheduledExecutorService

    三方框架 Quartz

    下面我们一个个来看。

    Timer和TimerTask

    先看一个小 demo,接着我们再来分析其中原理:

    253778149bf7eea1187a5478e55aad72.png

    这种方式的定时任务主要用到两个类,Timer 和 TimerTask。其中,TimerTask 继承接口 Runnable,抽象的描述一种任务类型,我们aTBzQjdx只要重写实现它的 run 方法就可以实现自定义任务。

    而 Timer 就是用于定时任务调度的核心类,demo 中我们调用其 schedule 并指定延时 1000 毫秒,所以上述代码会在一秒钟后完成打印操作,接着程序结束。

    那么,使用上很简单,两个步骤即可,但是其中的实现逻辑是怎样的呢?

    Timer 接口

    首先,Timer 接口中,这两个字段是非常核心重要的:

    5438179c2f503ca5da8d281ed34bfee8.png

    TaskQueue 是一个队列,内部由动态数组

    接着,这个 TimerThread 类其实是 Timer 的一个内部类,它继承了 Thread 并重写了其 run 方法,该线程实例将在构建 Timer 实例的时候被启动。

    run 方法内部会循环的从队列中取任务,如果没有就阻塞自己,而当我们成功的向队列中添加了定时任务,也会尝试唤醒该线程。

    我们也来看一下 Timer 的构造方法:

    public Timer(String name) {

    thread.setName(name);

    thread.start();

    }

    再简单不过的构造函数了,为内部线程设置线程名,并启动该线程。

    最后,我们着重看一下 Timer 中用于配置一个定时任务进任务队列的方法。

    //在时刻 time 处执行任务

    schedule(TimerTask task, Date time)

    //延时 delay 毫秒后执行任务

    schedule(TimerTask task, long delay)

    //固定延时重复执行,firstTime为首次执行时间,

    //往后没间隔 period 毫秒执行一次

    schedule(TimerTask task, Date firstTime, long period)

    //固定延时重复执行

    //首次执行时间为当前时间延时 delay 毫秒

    schedule(TimerTask task, long delay, long period)

    //固定频率重复执行,每过 period 毫秒执行一次

    scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

    //固定频率重复执行

    scheduleAtFixedRate(TimerTask task, long delay, long period)

    相信有了注释,这几个方法的区别与作用应该不难理解,但是其中有两个概念需要作一点区分。

    ==固定延时== VS ==固定频率==

    固定延时:以任务的上一次 实际 执行时间做参考,往后延时 period 毫秒。

    固定频率:任务的往后每一次执行时间都在任务提交的那一刻得到了确定,不论你上次任务是否意外延时了,定时定点执行下一次任务。

    这两者的区别还是很大的,希望你能够理解清楚,接着我们以其中一个方法为例,看看底层实现。

    以这个方法为例,其他重载方法的底层调用都是同样的,我们不去赘述。

    df895e0420e657eb5fcac46dfc162021.png

    这个方法的作用,我们再说一遍。

    以当前时间为准,延时 delay 毫秒后第一次执行该任务,并且采取固定延时的方式,每隔 period 毫秒再次执行该任务。

    开头的两个异常判断我们不再赘述,看看 sched 方法:

    108ed0d0b5cfdb34aa08ca845e8ae9da.png

    方法需要传入三个参数,参数 task 代表的需要执行的任务体,TimerTask 我们回头会详细介绍,这里你知道它代表了一个任务体即可。

    参数 time 描述了该任务下一次执行的时刻,计算机底层是以毫秒描述时刻的,所以这里转换为 long 类型来描述时刻。

    参数 period 是固定延时的毫秒数。

    整个方法的逻辑我们可以总结概括一下,具体的代码就不一行行分析了,因为也不难。

    首先使用任务队列的内置对象锁,锁住个队列。

    接着再去锁住我们的 task,并修改其内部的一些属性字段值,nextExecutionTime 指明下一次任务执行时间,period 设置固定延时的毫秒数,修改 state 状态为计划中。

    然后将 task 添加到任务队列,其中 add 方法内部会进行最小堆重构,参考的就是 nextExecutionTime 字段的值,越小优先级越高。

    判断如果自己就是队列第一个任务,那么将唤醒 Timer 中阻塞了的任务线程。

    可能会有人疑问,Timer 如何判断一个任务是否是重复执行的,还是单次执行就结束的?

    答案在 TimerThread 的 run 方法里,有兴趣你可以去研究下,方法体比较多比较长,这里不做分析。

    当我们构造 Timer 实例的时候,就会启动该线程,该线程会在一个死循环中尝试从任务队列上获取任务,如果成功获取就执行该任务并在执行结束之后做一个判断。

    如果 period 值为零,则说明这是一次普通任务,执行结束后将从队列首部移除该任务。

    如果 period 为负值,则说明这是一次固定延时的任务,修改它下次执行时间 nextExecutionTime 为当前时间减去 period,重构任务队列。

    如果 period 为正数,则说明这是一次固定频率的任务,修改它下次执行时间为 上次执行时间加上 period,并重构任务队列。

    其实,我也已经把 TimerThread 的 run 方www.cppcns.com法里最核心的逻辑也已经介绍了,建议大家亲自去研究研究具体代码的实现,你会对这一块的逻辑更清晰。

    最后,我们看一看这个 Timer 它有哪些劣势的地方:

    Timer 的背后只有一个线程,不管你有多少个任务,都只有一个工作线程,效率上必然是要打折扣的。

    限于单线程,如果第一个任务逻辑上死循环了,后续的任务一个都得不到执行。

    依然是由于单线程,任一任务抛出异常后,整个 Timer 就会结束,后续任务全部都无法执行。

    所以你看,单线程的 Timer 带来了太多局限性,于是我们看它的替代者。

    PS:本来计划再介绍下 TimerTask 这个抽象任务类的,但是发现实在没啥好介绍的,就是增加了两个字段,一个用于记录下一次该任务的执行时间,一个用于延时毫秒数。你也只需要重写其 run 方法即可。

    ScheduledExecutorService

    这个接口相信你一定眼熟,我告诉你在哪见过。

    adf54f35ebead90e2d90bc220102f2b6.png

    你看,它是我们异步框架中的接口,正好我们今天来介绍他,这样整个异步框架中所有的接口我们都分析过了。

    22d28ffa8f6eec66eb7f121c3285f115.png

    9564a204abc22411f37f24c763eee4e4.png

    ScheduledExecutorService中定义的这四个接口方法和 Timer 中对应的方法几乎一样,只不过 Timer 的 scheduled 方法需要在外部传入一个 TimerTask 的抽象任务。

    而我们的 ScheduledExecutorService 封装的更加细致了,随便你传 Runnable 或是 Callable,我会在内部给你做一层封装,封装一个类似 TimerTask 的抽象任务类(ScheduledFutureTask)。

    然后传入线程池,启动线程去执行该任务,而我们的 ScheduledFutureTask 重写的 run 方法是这样的:

    ded25eb941d710c6887ae4de3e745fc7.png

    如果 periodic 为 true 则说明这是一个需要重复执行的任务,否则说明是一个一次性任务。

    所以实际执行该任务的时候,需要分类,如果是普通的任务就直接调用 run 方法执行即可,否则在执行结束之后还需要重置下下一次执行时间。

    整体来说,ScheduledExecutorServwww.cppcns.com重新添加到任务队列。

    而对于后者来说,它只依赖一个线程不停的去获取队列首部的任务并尝试执行它,无论是效率上、还是安全性上都比不上前者。

    所以,建议使用 ScheduledExecutorService 取代 Timer,当然,通过学习 Timer 会更有助于对 ScheduledExecutorService 的研究。

    三方框架 Quartz

    除了上述两种定时任务框架外,Java 生态圈还存在一种开源的三方框架,他就是 Quartz。

    Quartz 是一个功能完善的任务调度框架,支持集群环境下的任务调度,需要将任务调度状态序列化到数据库。

    Quartz 已经是随着分布式概念的流行,成为企业级定时任务调度框架中的不二选择。

    Quartz 这个框架的使用及与原理在本篇就不做介绍了,我们会在后续介绍分布式概念的时候再来介绍它与 SpringCloud 平台下的整合使用情况。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

    本文标题: Java定时任务的三种实现方式

    本文地址: http://www.cppcns.com/ruanjian/java/251229.html

    展开全文
  • java 定时任务写法

    2012-11-20 14:55:48
    后台JAVA定时任务写法,可在夜间批处理执行业务处理
  • java基础教程介绍定时任务在实际的开发日子匆匆穿过我而行,奔向海洋。定时任务在实际的开发中特别常见,比如电商平台 30 分钟后自动取消未支付的订单,以及凌晨的数据汇总和备份等,都需要借助定时任务来实现,那么...

    java基础教程介绍定时任务在实际的开发

    ac0f99d16a23c5bc7c4ff4980e906ad3.png

    日子匆匆穿过我而行,奔向海洋。

    定时任务在实际的开发中特别常见,比如电商平台 30 分钟后自动取消未支付的订单,以及凌晨的数据汇总和备份等,都需要借助定时任务来实现,那么我们本文就来看一下定时任务最简单的几种实现方式。

    TOP 1:Timer

    Timer 是 JDK 自带的定时任务执行类,无论任何项目都可以直接使用 Timer 来实现定时任务,所以 Timer 的优点就是使用方便,它的实现代码如下:public class MyTimerTask {

    public static void main(String[] args) {

    // 定义一个任务

    TimerTask timerTask = new TimerTask() {

    @Override

    public void run() {

    System.out.println("Run timerTask:" + new Date());

    }

    };

    // 计时器

    Timer timer = new Timer();

    // 添加执行任务(延迟 1s 执行,每 3s 执行一次)

    timer.schedule(timerTask, 1000, 3000);

    }

    }

    程序执行结果如下:Run timerTask:Mon Aug 17 21:29:25 CST 2020

    Run timerTask:Mon Aug 17 21:29:28 CST 2020

    Run timerTask:Mon Aug 17 21:29:31 CST 2020

    Timer 缺点分析

    Timer 类实现定时任务虽然方便,但在使用时需要注意以下问题。

    问题 1:任务执行时间长影响其他任务

    当一个任务的执行时间过长时,会影响其他任务的调度,如下代码所示:public class MyTimerTask {

    public static void main(String[] args) {

    // 定义任务 1

    TimerTask timerTask = new TimerTask() {

    @Override

    public void run() {

    System.out.println("进入 timerTask 1:" + new Date());

    try {

    // 休眠 5 秒

    TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("Run timerTask 1:" + new Date());

    }

    };

    // 定义任务 2

    TimerTask timerTask2 = new TimerTask() {

    @Override

    public void run() {

    System.out.println("Run timerTask 2:" + new Date());

    }

    };

    // 计时器

    Timer timer = new Timer();

    // 添加执行任务(延迟 1s 执行,每 3s 执行一次)

    timer.schedule(timerTask, 1000, 3000);

    timer.schedule(timerTask2, 1000, 3000);

    }

    }

    程序执行结果如下:进入 timerTask 1:Mon Aug 17 21:44:08 CST 2020

    Run timerTask 1:Mon Aug 17 21:44:13 CST 2020

    Run timerTask 2:Mon Aug 17 21:44:13 CST 2020

    进入 timerTask 1:Mon Aug 17 21:44:13 CST 2020

    Run timerTask 1:Mon Aug 17 21:44:18 CST 2020

    进入 timerTask 1:Mon Aug 17 21:44:18 CST 2020

    Run timerTask 1:Mon Aug 17 21:44:23 CST 2020

    Run timerTask 2:Mon Aug 17 21:44:23 CST 2020

    进入 timerTask 1:Mon Aug 17 21:44:23 CST 2020

    从上述结果中可以看出,当任务 1 运行时间超过设定的间隔时间时,任务 2 也会延迟执行。 原本任务 1 和任务 2 的执行时间间隔都是 3s,但因为任务 1 执行了 5s,因此任务 2 的执行时间间隔也变成了 10s(和原定时间不符)。

    问题 2:任务异常影响其他任务

    使用 Timer 类实现定时任务时,当一个任务抛出异常,其他任务也会终止运行,如下代码所示:public class MyTimerTask {

    public static void main(String[] args) {

    // 定义任务 1

    TimerTask timerTask = new TimerTask() {

    @Override

    public void run() {

    System.out.println("进入 timerTask 1:" + new Date());

    // 模拟异常

    int num = 8 / 0;

    System.out.println("Run timerTask 1:" + new Date());

    }

    };

    // 定义任务 2

    TimerTask timerTask2 = new TimerTask() {

    @Override

    public void run() {

    System.out.println("Run timerTask 2:" + new Date());

    }

    };

    // 计时器

    Timer timer = new Timer();

    // 添加执行任务(延迟 1s 执行,每 3s 执行一次)

    timer.schedule(timerTask, 1000, 3000);

    timer.schedule(timerTask2, 1000, 3000);

    }

    }

    程序执行结果如下:进入 timerTask 1:Mon Aug 17 22:02:37 CST 2020

    Exception in thread "Timer-0" java.lang.ArithmeticException: / by zero

    at com.example.MyTimerTask$1.run(MyTimerTask.java:21)

    at java.util.TimerThread.mainLoop(Timer.java:555)

    at java.util.TimerThread.run(Timer.java:505)

    Process finished with exit code 0

    Timer 小结

    Timer 类实现定时任务的优点是方便,因为它是 JDK 自定的定时任务,但缺点是任务如果执行时间太长或者是任务执行异常,会影响其他任务调度,所以在生产环境下建议谨慎使用。

    TOP 2:ScheduledExecutorService

    ScheduledExecutorService 也是 JDK 1.5 自带的 API,我们可以使用它来实现定时任务的功能,也就是说 ScheduledExecutorService 可以实现 Timer 类具备的所有功能,并且它可以解决了 Timer 类存在的所有问题。

    ScheduledExecutorService 实现定时任务的代码示例如下:public class MyScheduledExecutorService {

    public static void main(String[] args) {

    // 创建任务队列

    ScheduledExecutorService scheduledExecutorService =

    Executors.newScheduledThreadPool(10); // 10 为线程数量

    // 执行任务

    scheduledExecutorService.scheduleAtFixedRate(() -> {

    System.out.println("Run Schedule:" + new Date());

    }, 1, 3, TimeUnit.SECONDS); // 1s 后开始执行,每 3s 执行一次

    }

    }

    程序执行结果如下:Run Schedule:Mon Aug 17 21:44:23 CST 2020

    Run Schedule:Mon Aug 17 21:44:26 CST 2020

    Run Schedule:Mon Aug 17 21:44:29 CST 2020

    ScheduledExecutorService 可靠性测试

    ① 任务超时执行测试

    ScheduledExecutorService 可以解决 Timer 任务之间相应影响的缺点,首先我们来测试一个任务执行时间过长,会不会对其他任务造成影响,测试代码如下:public class MyScheduledExecutorService {

    public static void main(String[] args) {

    // 创建任务队列

    ScheduledExecutorService scheduledExecutorService =

    Executors.newScheduledThreadPool(10);

    // 执行任务 1

    scheduledExecutorService.scheduleAtFixedRate(() -> {

    System.out.println("进入 Schedule:" + new Date());

    try {

    // 休眠 5 秒

    TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("Run Schedule:" + new Date());

    }, 1, 3, TimeUnit.SECONDS); // 1s 后开始执行,每 3s 执行一次

    // 执行任务 2

    scheduledExecutorService.scheduleAtFixedRate(() -> {

    System.out.println("Run Schedule2:" + new Date());

    }, 1, 3, TimeUnit.SECONDS); // 1s 后开始执行,每 3s 执行一次

    }

    }

    程序执行结果如下:Run Schedule2:Mon Aug 17 11:27:55 CST 2020

    进入 Schedule:Mon Aug 17 11:27:55 CST 2020

    Run Schedule2:Mon Aug 17 11:27:58 CST 2020

    Run Schedule:Mon Aug 17 11:28:00 CST 2020

    进入 Schedule:Mon Aug 17 11:28:00 CST 2020

    Run Schedule2:Mon Aug 17 11:28:01 CST 2020

    Run Schedule2:Mon Aug 17 11:28:04 CST 2020

    从上述结果可以看出,当任务 1 执行时间 5s 超过了执行频率 3s 时,并没有影响任务 2 的正常执行,因此使用 ScheduledExecutorService 可以避免任务执行时间过长对其他任务造成的影响。

    ② 任务异常测试

    接下来我们来测试一下 ScheduledExecutorService 在一个任务异常时,是否会对其他任务造成影响,测试代码如下:public class MyScheduledExecutorService {

    public static void main(String[] args) {

    // 创建任务队列

    ScheduledExecutorService scheduledExecutorService =

    Executors.newScheduledThreadPool(10);

    // 执行任务 1

    scheduledExecutorService.scheduleAtFixedRate(() -> {

    System.out.println("进入 Schedule:" + new Date());

    // 模拟异常

    int num = 8 / 0;

    System.out.println("Run Schedule:" + new Date());

    }, 1, 3, TimeUnit.SECONDS); // 1s 后开始执行,每 3s 执行一次

    // 执行任务 2

    scheduledExecutorService.scheduleAtFixedRate(() -> {

    System.out.println("Run Schedule2:" + new Date());

    }, 1, 3, TimeUnit.SECONDS); // 1s 后开始执行,每 3s 执行一次

    }

    }

    程序执行结果如下:进入 Schedule:Mon Aug 17 22:17:37 CST 2020

    Run Schedule2:Mon Aug 17 22:17:37 CST 2020

    Run Schedule2:Mon Aug 17 22:17:40 CST 2020

    Run Schedule2:Mon Aug 17 22:17:43 CST 2020

    从上述结果可以看出,当任务 1 出现异常时,并不会影响任务 2 的执行。

    ScheduledExecutorService 小结

    在单机生产环境下建议使用 ScheduledExecutorService 来执行定时任务,它是 JDK 1.5 之后自带的 API,因此使用起来也比较方便,并且使用 ScheduledExecutorService 来执行任务,不会造成任务间的相互影响。

    TOP 3:Spring Task

    如果使用的是 Spring 或 Spring Boot 框架,可以直接使用 Spring Framework 自带的定时任务,使用上面两种定时任务的实现方式,很难实现设定了具体时间的定时任务,比如当我们需要每周五来执行某项任务时,但如果使用 Spring Task 就可轻松的实现此需求。

    以 Spring Boot 为例,实现定时任务只需两步:开启定时任务;

    添加定时任务。

    具体实现步骤如下。

    ① 开启定时任务

    开启定时任务只需要在 Spring Boot 的启动类上声明 @EnableScheduling 即可,实现代码如下:@SpringBootApplication

    @EnableScheduling // 开启定时任务

    public class DemoApplication {

    // do someing

    }

    ② 添加定时任务

    定时任务的添加只需要使用 @Scheduled 注解标注即可,如果有多个定时任务可以创建多个 @Scheduled 注解标注的方法,示例代码如下:import org.springframework.scheduling.annotation.Scheduled;

    import org.springframework.stereotype.Component;

    @Component // 把此类托管给 Spring,不能省略

    public class TaskUtils {

    // 添加定时任务

    @Scheduled(cron = "59 59 23 0 0 5") // cron 表达式,每周五 23:59:59 执行

    public void doTask(){

    System.out.println("我是定时任务~");

    }

    }

    注意:定时任务是自动触发的无需手动干预,也就是说 Spring Boot 启动后会自动加载并执行定时任务。

    Cron 表达式

    Spring Task 的实现需要使用 cron 表达式来声明执行的频率和规则,cron 表达式是由 6 位或者 7 位组成的(最后一位可以省略),每位之间以空格分隔,每位从左到右代表的含义如下:

    a97c206f56385571c2f1b0f571e90bc7.png

    其中 * 和 ? 号都表示匹配所有的时间。

    ead907b78c43917677353455abb3e804.png

    cron 表达式在线生成地址:https://cron.qqe2.com/

    展开全文
  • java定时任务.java

    2021-07-21 16:14:05
    定时任务能直接使用不需要配置
  • 在 TimerManager 这个类里面,大家一定要注意 时间点的问题。如果你设定在凌晨2点执行任务。但你是在2点以后 ...发生,只能判断一下,如果发布或重启服务的时间晚于定时执行任务的时间,就在此基础上加一天。
  • 本篇文章主要介绍了Java Web项目中编写定时任务的实现,具有一定的参考价值,有兴趣的可以了解一下。
  • Java Web程序中加入定时任务,这里介绍两种方式使用监听器注入,使用Spring注解@Scheduled注入,需要的朋友可以参考下
  • 详解java定时任务

    2020-09-02 16:09:50
    主要为大家详细介绍了java定时任务,使用JDK中的Timer定时任务来实现,感兴趣的小伙伴们可以参考一下
  • 在开发测试工具的应用后台,需要定时任务做日志处理,或者数据清理,包括做些复杂的业务计算逻辑,在...一 Java 基本的定时任务,总结方法有三种:1.1 创建一个thread,然后让它在while循环里一直运行着,通过sleep...

    在开发测试工具的应用后台,需要定时任务做日志处理,或者数据清理,包括做些复杂的业务计算逻辑,在选择定时任务的时候,怎么能够快速实现,并且选择一种更适合自己的方式呢? 我这里把定时任务的实现收集整理了一些方法,希望可以帮到刚开始做定时任务的同学,写得不对的地方请指正。

    一  Java 基本的定时任务,总结方法有三种:

    1.1   创建一个thread,然后让它在while循环里一直运行着,通过sleep方法来达到定时任务的效果;

    20190414181725211453.png

    1.2   用Timer和TimerTask与第一种方法相比有如下好处:

    当启动和去取消任务时可以控制

    第一次执行任务时可以指定你想要的delay时间

    20190414181725509304.png

    1.3   用ScheduledExecutorService是从的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式,相比于上两个方法,它有以下好处:

    相比于Timer的单线程,它是通过线程池的方式来执行任务的

    可以很灵活的去设定第一次执行任务delay时间

    提供了良好的约定,以便设定执行的时间间隔

    20190414181725755398.png

    二  Spring 定时任务,总结方式也有三种:

    2.1    ScheduledTimerTask:  Spring的ScheduledTimerTask定义了一个定时器任务的运行周期,遗憾的是,你可以指定任务执行的频度,但你无法精确指定它何时运行,这就需要用到第二种Quartz进行任务调度;

    创建一个业务任务,在Spring配置文件中声明 ;

    在Spring 配置文件中,配置ScheduledTimerTask ,并且关联上自定义的任务实例;

    启动定时器,Spring的TimerFactoryBean负责启动定时任务

    20190414181726005398.png

    20190414181726403835.png

    2.2    使用 Quartz:

    首先还是老样子定义业务逻辑任务:

    20190414181726694851.png

    在Spring中声明并且配置作业调度的触发方式

    20190414181726850125.png

    20190414181727115750.png

    这里 Quartz的作业触发器有两种,分别是

    org.springframework.scheduling.quartz.SimpleTriggerBean

    org.springframework.scheduling.quartz.CronTriggerBean

    第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔一段时间运行一次。

    第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次,如上配置;

    配置调度工厂

    org.springframework.scheduling.quartz.SchedulerFactoryBean,代码如上;

    启动你的应用即可

    2.3   使用 Spring-Task

    Spring自带的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种:

    第一步:编写任务类;TaskJob,method job1  --代码省略

    第二步:在spring配置文件头中添加命名空间及描述

    xmlns:task="http://www.springframework.org/schema/task"

    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    第三步:spring配置文件中设置具体的任务

    说明:ref参数指定的即任务类,method指定的即需要运行的方法,cron及cronExpression表达式,具体写法这里不介绍了,spring扫描注解用的。

    文章转载至:https://blog.csdn.net/lchq1995/article/details/78222528

    展开全文
  • java动态管理定时任务

    2018-07-31 18:30:52
    spring+quartz整合,动态管理定时任务,可对正在进行的任务操作增删改查,可配合数据库进行操作
  • Java定时任务调度详解

    千次阅读 2021-04-07 08:32:07
    前言在实际项目开发中,除了Web应用、SOA服务外,还有一类不可缺少的,那就是定时任务调度。定时任务的场景可以说非常广泛,比如某些视频网站,购买会员后,每天会给会员送成长值,每月会给会员送一些电影券;比如在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 162,897
精华内容 65,158
关键字:

java定时任务

java 订阅