返回顶部
首页 > 资讯 > 后端开发 > Python >Java任务定时执行器案例的实现
  • 576
分享到

Java任务定时执行器案例的实现

2024-04-02 19:04:59 576人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录⭐️前面的话⭐️?1.定时器概述?1.1认识定时器?1.2Timer类的使用?2.定时器的简单实现⭐️前面的话⭐️ 本篇文章将介绍Java多线程案例,定时器,定时器就像闹钟一样,

⭐️前面的话⭐️

本篇文章将介绍Java多线程案例,定时器,定时器就像闹钟一样,等到了指定的时间,闹钟就会发出响声来提醒您,而定时器会执行指定的任务。

?1.定时器概述

?1.1认识定时器

java中的定时器,也可以叫做任务定时执行器,顾名思义,就是等到了指定的时间,就去做指定的事情,就像你每周六或周日都要去力扣参加周赛一样。

所以你如果想要使用定时器,你需要交代时间和对应的任务才行,java标准也提供了带有定时器功能的类Timer

?1.2Timer类的使用

在java1.8中,Timer给出了四个构造方法,这些构造方法可以去指定线程的名字和是否将定时器内部的线程指定为守护线程。

好了,又出现了一个新概念,这个守护线程是什么鬼?
其实在java中有两种线程,一种是用户线程,另外一种是守护线程。用户线程就是普通的线程,守护线程顾名思义就是守护用户线程的线程,可以说就是用户线程的保姆,守护线程与JVM“共存亡”, 只要存在一个用户线程,程序中所有的守护线程都不会停止工作,直到最后一个用户线程执行完毕,守护线程才会停止工作。守护线程最典型的应用就是 GC (垃圾回收器),它就是一个非常称职的守护者。

?构造方法:

序号构造方法说明
1public Timer()无参数构造方法,默认定时器关联的线程不是守护线程,线程名字也是默认值
2public Timer(boolean isDaemon)指定定时器中关联的线程是否为守护线程,如果是,参数为true
3public Timer(String name)指定定时器关联线程名称,线程类型默认为非守护线程
4public Timer(String name, boolean isDaemon)指定定时器关联线程名和线程类型

Timer类构造时内部也会创建线程,如果不指定,定时器对象内部的线程(为了简化,就称为关联线程吧)的类型是用户线程,而不是守护线程。

?核心方法:

序号方法说明
1public void schedule(TimerTask task, long delay)指定任务,延迟多久执行该任务
2public void schedule(TimerTask task, Date time)指定任务,指定任务的执行时间
3public void schedule(TimerTask task, long delay, long period)连续执行指定任务,延迟时间,连续执行任务的时间间隔,毫秒为单位
4public void schedule(TimerTask task, Date firstTime, long period)连续执行指定任务,第一次任务的执行时间,连续执行任务的时间间隔
5public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)与方法4作用相同
6public void scheduleAtFixedRate(TimerTask task, long delay, long period)与方法3作用相同
7public void cancel()终止定时器所有任务,终止执行的任务不受影响

?使用演示:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.PriorityBlockingQueue;

public class TimeProgram {
    public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行延后2s执行的任务!");
            }
        }, 2000);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行延后5s执行的任务!");
            }
        }, 5000);

        //每秒输出一个mian
        for (int i = 0; i < 5; i++) {
            System.out.println("main");
            Thread.sleep(1000);
        }
    }
}

?运行结果:

TimerTask类就是专门描述定时器任务的一个抽象类,它实现了Runnable接口。

public abstract class TimerTask implements Runnable    //jdk源码

下面我们简单实现一下定时器,我们就不用TimerTask了,我们直接使用Runnable,因为TimerTask实现了Runnable接口,所以后面测试我们自己所写的schedule方法时,也可以传入TimerTask类型的引用,既然是简单地实现,那就不实现连续执行的功能了。

?2.定时器的简单实现

首先,我们需要建造一个类,来描述定时器的任务,可以使用Runnable加上一个任务执行的时间戳就可以了。
?具体清单:
一个构造方法,用来指定任务和延迟执行时间。
两个获取方法,用来给外部对象获取该对象的任务和执行时间。
实现比较器,用于定时器任务对象的组织,毕竟,每次需要执行时间最早的任务,需要用到基于小根堆实现的优先队列,不,还需要考虑多线程的情况,还是使用优先级阻塞队列吧。

//我的任务
class MyTask implements Comparable<MyTask> {
    //接收具体任务
    private Runnable runnable;
    //执行时的时间戳
    private long time;

    //构造方法
    public MyTask(Runnable runnable, int delay) {
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

    //执行任务
    public void run() {
        this.runnable.run();
    }
    //获取执行时间
    public long getTime() {
        return this.time;
    }

    //实现comparable接口,方便创建优先级阻塞队列
    @Override
    public int compareTo(MyTask o) {
        return (int) (this.time - o.time);
    }
}

接下来就要实现定时器类了,首先我们需要一个数据结构来组织定时器任务,并且每次都能将时间最早的任务找到并执行,那么这个数据结构非小根堆莫属了,也就是优先级队列,注意对自定义类使用优先级队列时,一定要实现比较器。

    //每次执行任务时,需要优先执行时间在前的任务,即每次执行任务要选择时间戳最小的任务,在多线程情况中优先级阻塞队列是最佳选择
    private static final PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();

然后,需要一个方法将任务安排在优先级阻塞队列中,最后在构造定时器对象的时候从优先级阻塞队列中取任务并在指定的时间执行。

按照上图的逻辑,我们自己实现的定时器类需要有一个线程专门去执行任务,执行任务过程中可能会遇到执行时间还没有到的情况,那么线程必须得等待,线程等待的方法有两种,一种是wait另一种是sleep,这个案例我们推荐前者,因为sleep方法不能中途唤醒,这个案例是有可能需要中途唤醒的,那就是有新任务插入时,需要重新去优先级阻塞队列拿任务重复上述操作,这个唤醒操作可以使用notify方法实现,所以需要用到wait/notify组合拳,既然需要使用wait/notify那么就得有,所以我们可以使用一个专门的锁对象来加锁。

?实现代码:

//我的定时类 用来管理任务
class MyTimer {
    //专门对锁对象
    private final Object locker = new Object();
    //每次执行任务时,需要优先执行时间在前的任务,即每次执行任务要选择时间戳最小的任务,在多线程情况中优先级阻塞队列是最佳选择
    private static final PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();

    //安排任务
    public void schedule(Runnable runnable, int delay) {
        //将任务放入小根堆中
        MyTask task = new MyTask(runnable, delay);
        priorityBlockingQueue.put(task);
        //每次当新任务加载到阻塞队列时,需要中途唤醒线程,因为新进来的任务可能是最早需要执行的
        synchronized (locker) {
            locker.notify();
        }
    }
    public MyTimer() {
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    //加载任务,确定执行时机
                    MyTask myTask = priorityBlockingQueue.take();
                    long curTime = System.currentTimeMillis();
                    //时间未到,将任务放回
                    if (curTime < myTask.getTime()) {
                        synchronized (locker) {
                            priorityBlockingQueue.put(myTask);
                            //放回任务后,不能立即就再次取该任务加载,需要设置一个再次加载的等待时间,建议使用wait带参数的方法
                            //因为wait方法可以使用notify进行中途唤醒,而sleep不能中途唤醒
                            int delay = (int)(myTask.getTime() - curTime);
                            locker.wait(delay);
                        }
                    } else {
                        System.out.println(Thread.currentThread().getName() + "线程收到任务,正在执行中!");
                        myTask.run();
                        System.out.println(Thread.currentThread().getName() + "线程执行任务完毕,正在等待新任务!");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //不要忘了启动线程
        thread.start();
    }
}

?上面是我们实现定时器的代码,我们来测试一下:

import java.util.TimerTask;
import java.util.concurrent.PriorityBlockingQueue;

public class TimeProgram {
    public static void main(String[] args) throws InterruptedException {
        MyTimer timer = new MyTimer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行延后2s执行的任务!");
            }
        }, 2000);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("执行延后5s执行的任务!");
            }
        }, 5000);

        //每秒输出一个mian
        for (int i = 0; i < 5; i++) {
            System.out.println("main");
            Thread.sleep(1000);
        }
    }
}

?执行结果:

好了,任务定时执行器你学会了吗?

到此这篇关于Java任务定时执行器案例的实现的文章就介绍到这了,更多相关Java任务定时执行器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java任务定时执行器案例的实现

本文链接: https://lsjlt.com/news/150648.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java任务定时执行器案例的实现
    目录⭐️前面的话⭐️1.定时器概述1.1认识定时器1.2Timer类的使用2.定时器的简单实现⭐️前面的话⭐️ 本篇文章将介绍Java多线程案例,定时器,定时器就像闹钟一样,等到了指...
    99+
    2024-04-02
  • java实现周期性执行(定时任务)
    最近是遇到一个设备在线离线的判定问题,设计是每个多长时间(常规的定时任务)检测一次设备是否在前,当检测到里离线时,我们不能立马判断为离线,而是要在重试多测几次,只要一次成功就返回判定...
    99+
    2024-04-02
  • java如何定时执行任务
    java如何定时执行一个方法java实现定时功能有多种方式,下面介绍3种:1、创建一个线程.import java.util.Date; public class ThreadTest { public static void ma...
    99+
    2022-04-07
    java基础 java 定时
  • java web如何实现每天定时执行任务
    小编给大家分享一下java web如何实现每天定时执行任务,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!package com.eh.util;import java.util.Calendar;imp...
    99+
    2023-05-30
  • android定时执行任务怎么实现
    Android定时执行任务可以通过以下几种方式实现:1. 使用Handler和Timer:创建一个Handler对象,在Handle...
    99+
    2023-09-21
    android
  • php怎么实现定时执行任务
    在PHP中,可以使用以下几种方法来实现定时执行任务:1. 使用cron表达式:cron表达式是一种常用的定时任务调度语法,可以在操作...
    99+
    2023-08-12
    php
  • spring执行定时任务
    定义一个任务是很简单的实现TimerTask的run方法就可以了.如下:SayHelloTask.javapackage test.timerTask;import java.util.TimerTask;public class SayH...
    99+
    2023-06-03
  • Linux下实现Mysql定时任务的案例
    小编给大家分享一下Linux下实现Mysql定时任务的案例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!假设前提:每天晚上10点...
    99+
    2024-04-02
  • Java ScheduledExecutorService定时任务案例讲解
    一、ScheduledExecutorService 设计思想 ScheduledExecutorService,是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线...
    99+
    2024-04-02
  • Linux中如何实现crontab定时执行任务
    小编给大家分享一下Linux中如何实现crontab定时执行任务,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!基本格式 : *  *  *  *  *  comm...
    99+
    2023-06-13
  • Laravel每秒执行定时任务怎么实现
    这篇文章主要介绍“Laravel每秒执行定时任务怎么实现”,在日常操作中,相信很多人在Laravel每秒执行定时任务怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Laravel每秒执行定时任务怎么实现...
    99+
    2023-07-04
  • @Scheduled 定时任务不执行
    一、排查代码中添加的定时任务步骤是否正确 启动类上加 @EnableScheduling 注解定时任务类上加@Component定时方法上加@Scheduled @Scheduled(cron = "0 19 16 * * ") ...
    99+
    2023-08-30
    java
  • Java实现定时任务的示例代码
    目录xxl-job官网引入依赖配置信息(application.properties)配置类(XxlJobConfiguration)调用xxl-job-admin模块的接口添加调度...
    99+
    2022-11-21
    Java实现定时任务 Java定时任务 Java 定时
  • Java使用线程池执行定时任务
    目录1.schedule2.scheduleAtFixedRate3.scheduleWithFixedDelay总结前言: 在 Java 语言中,有两个线程池可以执行定时任务:Sc...
    99+
    2024-04-02
  • Java实现定时任务
    本文实例为大家分享了Java实现定时任务的具体代码,供大家参考,具体内容如下 1 使用java.util.Timer 这种方式的定时任务主要用到两个类,Timer 和 TimerTa...
    99+
    2024-04-02
  • php ignore_user_abort()实现计划(定时执行)任务功能
    要实现计划任务功能,可以使用ignore_user_abort()函数来忽略用户中断,并且在后台继续执行脚本。以下是一个示例,展示了...
    99+
    2023-10-11
    php
  • Java之SpringBoot定时任务案例讲解
    1. SpringBoot--任务:定时任务 项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候, 分析一次前一天的日志信息,Spring为我们提供了异步执行任务调度的...
    99+
    2024-04-02
  • springboot执行延时任务之DelayQueue实例
    目录springboot执行延时任务之DelayQueueDelayQueue是什么?使用步骤日常开发延迟任务技术对比总结springboot执行延时任务之DelayQueue 提示...
    99+
    2023-02-14
    springboot执行延时任务 springboot DelayQueue springboot延时任务
  • django定期执行任务(实例讲解)
    要在django项目中定期执行任务,比如每天一定的时间点抓取数据,刷新数据库等,可以参考stackoverflow的方法,先编写一个manage.py命令,然后使用crontab来定时执行这个命令。 定制m...
    99+
    2022-06-04
    实例 django
  • Python定时任务实现方案
    目录1、定时任务2、Python的定时任务2.1 几种常见的方案2.1.1 schedule2.1.2 Jenkins2.1.3 Celery2.2 题外话之持久化2.2.1 ApS...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作