<多线程章节十> 定时器的使用方法以及定时器的模拟实现

news2024/11/17 6:53:27

文章目录

  • 💐专栏导读
  • 💡Java标准库中的定时器类
  • 💡模拟实现定时器

💐专栏导读

本篇文章收录于多线程,也欢迎翻阅博主的其他文章,可能也会让你有不一样的收获😄
🍂JavaSE🌷多线程🍁数据结构

闹钟大家一定都使用过,当闹钟响的时候,就表示我们该起床了,或者是手机上的定时发短信,等到时间达到时,就会按照我们的要去发送短信等;定时器也就是这样一种工作组件,约定一个时间,当时间达到时,就会执行代码

定时器经常用于网络通信中,例如,当客户端向服务器发出一个请求后,就要等待服务器进行响应,但是,如果服务器一直没响应怎么办,是因为请求没发过去?响应没传过来?服务器出问题了等等,这中间你也不知道发生了什么,这时候,客户端难道就一直等着,等到天荒地老?所以,对于客户端而言,就需要一个等待时间,如果等待时间到了,是重新再发送一遍,还是放弃发送,还是其他的操作等等………

💡Java标准库中的定时器类

在Java的util包中,提供了一个Timer类,这个类就是一个定时器,下面通过代码演示:

public class MyTimer {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            //给定时器安排一个任务,约定在xxx时间后开始执行
            @Override
            public void run() {
                System.out.println("定时器中任务开始执行");
            }
        }, 3000);//指定定时时间,约定在三秒之后开始执行
        System.out.println("程序执行");
    }
}

在这里插入图片描述

在执行schedule方法的时候,就是把这个任务放到了timer对象中,而且,在timer对象中,也包含了一个线程,这个线程叫作”扫描线程“,等约定时间到了以后,扫描线程就开始执行这个任务;然后通过执行结果也可以看到,定时器中的任务执行完之后,进程并没有结束,而是处于等待其他任务安排进来,所以由此得出,Timer中的线程会阻止进程结束,在Timer中同样也可以安排多个任务👇

在这里插入图片描述

在学习完如何使用一个定时器后,我们应该还知道如何实现一个简单的定时器👇

💡模拟实现定时器

实现一个定时器主要考虑一下几个步骤:

 class MyTimerTask {
        //顶一个一个任务
    private Runnable runnable;
    //定义一个定时时间
    public long time;
    public MyTimerTask(Runnable runnable, long delay) {
        this.runnable = runnable;
        this.time = System.currentTimeMillis()+delay;
    }
    public Runnable get_runnable() {
        return runnable;
    }
}
public class MyTimer {
   //定义一个队列用于组织任务
    private PriorityQueue<MyTimerTask> priorityQueue = new PriorityQueue<>(new Comparator<MyTimerTask>() {
        //自定义比较方法
       @Override
       public int compare(MyTimerTask o1, MyTimerTask o2) {
           return (int)(o1.time - o2.time);
       }
   });

    //定义一个锁对象
    Object locker = new Object();

    //定义一个schedule方法
    public void schedule(Runnable runnable, long time) {

        /*
        因为是其他的线程调用schedule,然后对队列进行操作,而扫扫描线程也是对队列进行操作,
        这也就构成了两个线程对同一个数据进行操作,就可能会出现线程安全问题,因此要进行加锁
         */
        synchronized (locker) {
            priorityQueue.offer(new MyTimerTask(runnable, time));
            locker.notify();
        }
    }

    //在构造方法中定义一个扫描线程
    public MyTimer() {
        Thread thread = new Thread(() -> {
            while(true) {
                //检查队列中的任务
                check_task();
            }
        });
        thread.start();
    }
    private void check_task() {
        try {
            synchronized (locker) {
                //当队列为空时,阻塞等待
                //使用while进行判断,防止唤醒wait时,队列仍然为空
                while (priorityQueue.isEmpty()) {
                    locker.wait();
                }
                MyTimerTask myTimerTask = priorityQueue.peek();
                //判断当前时间与定时时间
                long curTime = System.currentTimeMillis();
                if(curTime >= myTimerTask.time) {
                    //当前时间大于定时时间,开始执行任务
                    myTimerTask.get_runnable().run();
                    //任务执行完后删除
                    priorityQueue.poll();
                }else {
                    //为了防止忙等,在这里进行带有时间的wait等待
                    //当时间到了以后,再进行循环,开始执行任务
                    locker.wait(curTime - myTimerTask.time);
                }
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Studio One6.5新版本功能介绍及下载图文教程

studio one6更新了。studio one终于迎来了期待已久的6.5版本&#xff0c;增加了杜比全景声环绕声等混音模式&#xff0c;让我们混音更加方便&#xff01;Studio One 6破是一个功能完整的工作站&#xff0c;不止于专业的音乐制作和编辑&#xff0c;Studio One也是一个直播表演工…

计算机视觉 激光雷达结合无监督学习进行物体检测的工作原理

一、简述 激光雷达是目前正在改变世界的传感器。它集成在自动驾驶汽车、自主无人机、机器人、卫星、火箭等中。该传感器使用激光束了解世界,并测量激光击中目标返回所需的时间,输出是点云信息,利用这些信息,我们可以从3D点云中查找障碍物。 从自动驾驶汽车的角度看激光雷达…

MySQL启动后反复重新启动故障

MySQL版本为5.6.45 系统为Ubuntu 20.04 LTS 该服务器重启后&#xff0c;MySQL需要手动执行启动。 运行执行脚本后发现异常&#xff0c;如下图&#xff1a; 提示MySQL服务在不停重复启动。 反复使用ps -ef |grep mysql命令查看&#xff0c;发现mysql进程号一直在变化&#x…

ChatGLM推出第三代基座大模型在论文阅读、文档摘要和财报分析等方面提升超过50%推理成本降低一半...

“ 智谱AI发布了第三代基座大模型ChatGLM3&#xff0c;在模型性能、功能支持、开源序列等方面进行了全面升级。ChatGLM3在语义、数学、推理、代码、知识等不同角度的数据集上测评显示&#xff0c;具有在10B以下的基础模型中最强的性能。同时&#xff0c;ChatGLM3还支持多模态理…

数据库的概念和sql语句

数据&#xff1a;数字信息 据&#xff1a;就是属性 对一系列对象的具体属性的描述的集合 数据库&#xff1a;数据库就是用来组织&#xff08;各个数据之间是有关联。是按照规则组织起来的&#xff09;&#xff0c;存储和管理&#xff08;对数据的增删改查&#xff09;的仓库 …

推荐一本书《变速领导力》

大家好,这里是大话硬件。 今天想再给大家推荐一本书《变速领导力》。前段时间推荐的《横向领导力》在国庆假期内已经全部读完了,目前在进行二刷,边刷边做思维导图笔记。 就在二刷横向领导力的同时,假期还带了一本书回来《变速领导力》。这本书是在公司无意中看到其他组的…

【C语言_文件_进程_进程间通讯 常用函数/命令 + 实例】.md_update:23/10/27

目录&#xff1a; 文件相关命令进程相关命令getpid(); fork(); vfork();exit(6);wait(status); WEXITSTATUS(status);exec组函数 对比 system popen &#xff1a;精彩博文跳转&#xff1a; 进程间通讯精彩博文跳转pipe 无名管道mkfifo 有名管道消息队列共享内存_映射信号编程查…

139.【JUC并发编程-04】

JUC-并发编程04 (八)、共享模型之工具1.线程池(1).自定义线程池_任务数小于队列容量(2).自定义线程池_任务数大于队列容量(3).自定义线程池_拒绝策略 2.ThreadPoolExecutor(1).线程池状态(2).构造方法(3).newFixedThreadPool (固定大小线程池)(4).newCachedThreadPool (缓存线程…

企业内部IM即时聊天软件WorkPlus,自主可控的信创即时通讯IM

随着国家的发展发展&#xff0c;很多技术因为一些原因越来越受制于人&#xff0c;尤其是上游核心技术。为了解决这个问题&#xff0c;我国明确了“数字中国”建设战略&#xff0c;强调“自主”、“安全”、“可控”&#xff0c;不被“卡脖子”。在信创产业链的各环节中&#xf…

Linux中shell脚本中的变量

目录 一、变量的定义 二、shell脚本中变量的定义方法 1、变量名称 2、环境级别 3、用户级别 4、系统级别 5、删除设定的变量 三、变量的转译 1、转译 2、声明 3、变量的数组 四、Linux中命令的别名设定 五、用户环境变量的更改 脚本中的传参 1、非交互模式 2…

【VPX611】基于6U VPX总线架构的SATA3.0高性能数据存储板(3.2GByte/s存储带宽)

VPX611是一款基于6U VPX总线架构的高性能数据存储板&#xff0c;该板卡采用2片Xilinx Kintex-7系列FPGA作为主控单元&#xff0c;FPGA内嵌RAID控制器&#xff0c;最大支持8个mSATA盘&#xff0c;最大存储容量可以达到8TByte&#xff0c;持续数据写入带宽可以达到3.2GByte/s。板…

【运维】fstab,systemctl与rc.local启动顺序

前言: 在redis,mongo服务添加systemctl enable启动的情况下&#xff0c;redis和Mongo没有正常启动。排查日志得知,使用到的路径没有挂载。下面截图中的/var/lib/redis和mongo都是软连接&#xff0c;指向了一个服务器的本地盘。 经过排查/var/log/messages以及查阅相关日志得出:…

微积分(三) 不定积分和定积分

前言 微分法也有它的逆运算——积分法。我们已经知道&#xff0c;微分法的基本问题是研究如何从已知函数求出它的导函数&#xff0c;那么与之相反的问题是&#xff1a;求一个未知函数&#xff0c;使其导函数恰好是某一已知函数。 不定积分 假设已知函数A,一个个关于面积的函…

【Linux】NFS服务器搭建配置挂载(Linux挂载Windows目录)

本篇作用于Linux挂载Windows目录&#xff0c;如需要Linux挂载Linux目录请移步我的另一篇文章 http://t.csdnimg.cn/lVrC6http://t.csdnimg.cn/lVrC6 一、Windows端操作步骤 1、创建windows目录&#xff0c;右键目录>属性 2、共享选项>共享按钮>选择Administrator&…

【Python爬虫三天从0到1】Day1:爬虫核心

目录 1.HTTP协议与WEB开发 &#xff08;1&#xff09;简介 &#xff08;2&#xff09;请求协议和响应协议 2. requests&反爬破解 &#xff08;1&#xff09;UA反爬 &#xff08;2&#xff09;referer反爬 &#xff08;3&#xff09;cookie反爬 3.请求参数 &#x…

基于springboot实现校园交友网站管理系统项目【项目源码+论文说明】

基于springboot实现校园交友网站管理系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生…

为什么说大模型微调是每个人都必备的核心技能?

▼最近直播超级多&#xff0c;预约保你有收获 近期直播&#xff1a;《基于开源 LLM 大模型的微调&#xff08;Fine tuning&#xff09;实战》 0 — 为什么要对 LLM 大模型进行微调&#xff08;Fine tuning&#xff09;&#xff1f; LLM 大模型&#xff08;比如&#xff1a;Chat…

python自动化测试(三):xpath获取元素

目录 前置代码 一、什么是xpath方式 二、通过xpath 单组属性名属性值 的方式进行元素定位 三、通过xpath的多组属性进行元素的定位 四、通过xpath文本值的方式进行元素定位 五、通过模糊的文本值方式进行元素定位 前置代码 # codingutf-8 from selenium import webdrive…

export declare const TestService和export const TestService的区别

两者的主要区别在于导出方式的差异和访问方式的差异。 export declare const TestService&#xff1a;这种方式使用了export declare语法来导出一个常量TestService。export declare语法告诉编译器&#xff0c;此处的声明是供其他模块使用的&#xff0c;但是在当前模块中并没有…

Could not update Flowable database schema: unknown version from database:

文章目录 一、出现问题的情况二、解决方法1、 act_ge_property这个表里面的版本改成flowable-engine的版本号2、act_id_property表的schema.version版本也改成和flowable-engine版本一致&#xff08;如图所示&#xff09; 一、出现问题的情况 项目集成flowable流程框架的时候&…