iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java简单实现定时器
  • 946
分享到

Java简单实现定时器

2024-04-02 19:04:59 946人浏览 独家记忆

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

摘要

本文实例为大家分享了Java简单实现定时器的具体代码,供大家参考,具体内容如下 一、定时器 定时器相当于一个任务管理器。有些任务可能现在执行, 有些任务可能过1个小时,甚至很久才会执

本文实例为大家分享了Java简单实现定时器的具体代码,供大家参考,具体内容如下

一、定时器

定时器相当于一个任务管理器。有些任务可能现在执行, 有些任务可能过1个小时,甚至很久才会执行。定时器就是对这些任务进行管理监视, 如果一个任务执行时间到了,定时器就会将这个任务执行。 保证所有的任务都会在合适的时间执行。

二、定时器的实现

对于定时器的实现,我们可以划分为3个部分。

1、 使用一个Task类描述每一个任务(里面包含任务的执行方法, 定时时间)。
2、 使用优先级队列管理这些任务类。

2.1 我们都知道优先级队列底层实现是堆(以小根堆为例), 堆顶的元素是所有的元素的最小值。 我们以任务的定时时间为比较原则构建, 这样就可以保证堆顶元素的任务执行时间是最短的(这样的实现,我们需要在Task类内部定义比较规则-即重写Comparable接口的CompareTo方法)。

2.2 当一个任务执行完毕, 就会从优先级队列取出poll掉, 然后内部重新组织保证新的堆顶元素是定时时间最短的。

2.3 如果说堆顶的任务定时时间还没有到达(当然后续的任务定时时间肯定会更长,不会被执行)

3、使用一个线程循环扫描优先级队列, 相当于一个监控线程,循环判断堆顶任务是否满足执行时间。

三、定时器的组成

1、制定任务类Task

Task类包含任务的 执行方法 和 定时时间。

1.1 执行方法我采用封装Runnable中run方法实现, 这样做是为了后续添加任务时方便写执行逻辑。
1.2 定时时间就是long类型的变量
1.3 制定比较规则, 后续优先级队列中存放的是Task对象(而在内部构建时,需要比较两个Task对象的),对于对象的比较, 我们以对象的定时时间为规则, 制定小根堆。


static class Task implements Comparable<Task>{
        //Runnable类中有一个run方法, 通过这个方法实现任务的执行
        private Runnable command;
        //time表示执行的时间
        private long time;

        //构造方法
        public Task(Runnable command, long time) {
            this.command = command;
            this.time = System.currentTimeMillis() + time;  //将时间转化为绝对时间
        }

        //执行任务的逻辑
        public void run() {
            command.run();
        }

        //定义比较方法 - 方便后续的优先级队列构建

        @Override
        public int compareTo(Task o) {
            return (int)(this.time - o.time);
        }
    }

2、监管线程&定时器对象Timer

监管线程Worker中包含优先级队列(小根堆)queue 和 循环监管的流程。

Timer对象封装了监管线程Woker 和 任务的添加方法schedule()

关于监管线程的优化

2.1 循环监控存在一个弊端,那就是一直循环判断, 占用CPU资源。
(假如堆首任务的执行是1小时后, 再次期间监管线程会跑1小时循环判断。) 

解决方法: 可以通过线程阻塞和唤醒来解决。在下面代码有详细注释和实现。

2.1.1 如果任务1小时后执行, 我们让监管线程wait(1小时), 但在此期间如果有新的任务添加进来(可能新的任务需要等30分钟就可以执行,堆首元素发生变化) ,这时需要唤醒监管线程来重新判断。(由于wait和notify方法不在用一个类中实现, 我们通过一个Object(mailBox)来阻塞、唤醒)


//检测线程, 继承Thread类,重写内部run方法,属于线程的创建方法之一。
    static class Worker extends Thread {
     //优先级队列 - JUC包里面
        private PriorityBlockingQueue<Task> queue = null;
        //为了对监管线程进行阻塞和唤醒,采用同一对象
        private Object mailBox = null;
  
  //构造函数
        public Worker(PriorityBlockingQueue<Task> queue, Object mailBox) {
            this.queue = queue;
            this.mailBox = mailBox;
        }

        @Override
        public void run() {
            //实现具体的执行逻辑
            while(true) {
                try {
                    //1、取优先级队列的队首元素
                    Task task = queue.peek();
                    //2、比较队首的元素的时间是否大于当前时间
                    if(task == null) {
                        continue;
                    }
                    long curTime = System.currentTimeMillis();
                    if(task.time > curTime) {
                        //时间还没有到, 由于取出了任务, 需要重新放置回去
                        //优化1: 空循环等待 - wait(time) 让线程休眠time时间,然后在执行
                        //       如果在等待期间有新的任务添加, 这个时候我们唤醒线程, 继续判断(因为存在新的时间过短需要立即执行)
                        //       这个只需要添加一个新任务时, 唤醒即可
                        //优化2: 访问队首元素而不是取出, 防止无所谓的删除、插入。(维护优先级队列是有消耗的)
                        long gapTime = task.time - curTime;
                        synchronized (mailBox) {
                            mailBox.wait(gapTime);
                        }
                    }
                    else {
                        //直接执行
                        //如果执行到了, 则会删除头部元素, 调用任务的执行过程。
                        task = queue.take();
                        task.run();
                    }
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    }

    //定时器简单实现
    static class Timer {
        //定时器的实现步骤
        //1、用一个类描述任务
        //2、用优先级队列管理这些任务, 比较方法通过任务的制定时间,每次取队首元素
        //   队首元素是执行时间最近的
        private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
        //3、用一个线程来循环扫描当前的阻塞队列,判断队首的执行时间, 如果执行时间到了,那就执行。

        //4、创建一个Object对象,用于设置线程阻塞使用的, 存在线程阻塞, 添加任务时唤醒的操作
        private Object mailBox = new Object();

        //构造函数
        public Timer() {
            //创建线程
            Worker worker = new Worker(queue, mailBox);
            worker.start();
        }


        //4、提供一个方法, 让调用者能够把任务安排起来
        public void schedule(Runnable command, long time) {
            Task task = new Task(command, time);
            queue.put(task);
            synchronized (mailBox) {
                mailBox.notify();
            }
        }
    }

3、测试代码

其中添加了4个任务, 分别是2s、5s、7s、10s后执行。


public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("郝梦武一号任务执行, 执行代号:闪电;  定时时间:2s");
            }
        }, 2000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("郝梦武二号任务执行, 执行代号:暴风;  定时时间:5s");
            }
        }, 5000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("郝梦武三号任务执行, 执行代号:狂风;  定时时间:7s");
            }
        }, 7000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("郝梦武三号任务执行, 执行代号:地震;  定时时间:10s");
            }
        }, 10000);
    }

4、测试结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Java简单实现定时器

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java简单实现定时器
    本文实例为大家分享了Java简单实现定时器的具体代码,供大家参考,具体内容如下 一、定时器 定时器相当于一个任务管理器。有些任务可能现在执行, 有些任务可能过1个小时,甚至很久才会执...
    99+
    2024-04-02
  • SpringBoot简单实现定时器过程
    目录前言正文定时器的实现cron表达式详解总结前言 公司最近需要完成一个定时去DB查询数据,把有问题的数据给筛选出来通过微信小程序的消息推送功能将有问题的数据推送给指定的员工去筛查问...
    99+
    2023-05-16
    Springboot定时器 Springboot定时器实现
  • Java实现一个简单的定时器代码解析
    定时的功能我们在手机上见得比较多,比如定时清理垃圾,闹钟,等等.定时功能在java中主要使用的就是Timer对象,他在内部使用的就是多线程的技术.Time类主要负责完成定时计划任务的功能,就是在指定的时间的开始执行某个任务.Timer类的作...
    99+
    2023-05-30
    java 定时器 ava
  • Java实现定时任务最简单的3种方法
    目录一、Timer二、ScheduledExecutorService三、Spring Task1、开启定时任务2、添加定时任务Cron 表达式知识扩展:分布式定时任务1、ZSet ...
    99+
    2024-04-02
  • 基于Python怎样实现简单的定时器
    基于Python怎样实现简单的定时器,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。所谓定时器,是指间隔特定时间执行特定任务的机制。几乎所有的编程语言,都有定时器...
    99+
    2023-06-22
  • Java 定时任务-最简单的3种实现方法
     一、Timer Timer是JAVA自带的定时任务类,实现如下: public class MyTimerTask {     public static void main(String[] args) {         ...
    99+
    2023-09-02
    java Java 定时任务 Spring 定时任务 java 定时任务 spring 定时任务
  • 基于Python实现简单的定时器详解
    所谓定时器,是指间隔特定时间执行特定任务的机制。几乎所有的编程语言,都有定时器的实现。比如,Java有util.Timer和util.TimerTask,JavaScript有set...
    99+
    2024-04-02
  • JavaScript实现简单计时器
    本文实例为大家分享了JavaScript实现简单计时器的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"&g...
    99+
    2024-04-02
  • java简单实现自定义日历
    本文实例为大家分享了java自定义日历的具体代码,供大家参考,具体内容如下 效果图: 源码: package com.example; import java.text.Simp...
    99+
    2024-04-02
  • 你知道吗?Java在Unix上实现实时重定向超级简单!
    当今软件开发领域中,Java已经成为最流行的编程语言之一。Java的高效性和跨平台特性使其成为开发人员的首选语言。但是,Java在Unix上的实时重定向却是一个相对较难的问题。在本文中,我们将向您展示如何在Unix上使用Java实现实时重定...
    99+
    2023-10-02
    重定向 实时 unix
  • vue.js实现简单计时器功能
    本文实例为大家分享了vue.js实现简单计时器功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> ...
    99+
    2024-04-02
  • Vue.js实现简单计时器应用
    本文实例为大家分享了Vue.js实现简单计时器应用的具体代码,供大家参考,具体内容如下 一、计时器 1、在data中定义数据:比如num用来计时; 2、menthods中的添加两个方...
    99+
    2024-04-02
  • Android定时器Timer简单使用
    在Android中,可以使用`Timer`类来创建定时器,实现定时执行某个任务的功能。以下是一个简单的使用示例:1. 创建一个`Ti...
    99+
    2023-10-12
    Android
  • JS实现简单网页倒计时器
    制作一个简单的网页倒计时器(js原生代码),供大家参考,具体内容如下 实现一个简单的网页倒计时(距离xx年x月x日还剩多少时间),效果是这样的 首先HTML代码部分,我们需要简单编...
    99+
    2022-11-13
    JS网页倒计时器 JS倒计时器 JS网页倒计时
  • 简单实现java音乐播放器
    学习过java语言的你,或多或少,在某天突发奇想,想着用swing做一个音乐播放器。但是,发现很难找到,相关的java代码,或者你下载的代码有问题,或者你代码里面引入的类包找不到。为了解决自如此类的问题。在这儿,有如下的代码可以供大家参考。...
    99+
    2023-05-31
    java 播放器 ava
  • Java实现简单聊天机器人
    本文实例为大家分享了Java实现简单聊天机器人的具体代码,供大家参考,具体内容如下 整个小案例:整合了Java socket编程、jdbc知识(ORM/DAO) 创建数据库和表,准备...
    99+
    2024-04-02
  • Java实现一个简单计算器
    先来看看界面效果: 源码如下: package test1;   import java.awt.Frame; import java.awt.TextField; import ...
    99+
    2024-04-02
  • js实现简单圆盘时钟
    本文实例为大家分享了js实现简单圆盘时钟的具体代码,供大家参考,具体内容如下 预览图: 代码: css: <style> .disc { ...
    99+
    2024-04-02
  • java简单手写版本实现时间轮算法
    时间轮 关于时间轮的介绍,网上有很多,这里就不重复了 核心思想 一个环形数组存储时间轮的所有槽(看你的手表),每个槽对应当前时间轮的最小精度 超过当前时间轮最大表示范围的会...
    99+
    2024-04-02
  • JavaScript实现简单钟表时钟
    本文实例为大家分享了JavaScript实现简单钟表时钟的具体代码,供大家参考,具体内容如下 效果图: 主要思想: 1.先画一个圆表盘。 2.再用js循环画刻度(每一个刻度都是li...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作