多线程新手村4--定时器

news2024/11/17 1:55:17

定时器是日常开发中很常见的组件,定时器大家可能不知道是干什么的,但是定时炸弹肯定都听过,定个时间,过一段时间后bomb!!!爆炸

定时器的逻辑和这个一样,约定一个时间,这个时间到达之后,执行某个代码逻辑;定时器的常见场景有网络通信,定时邮件发送等等。

计算机网络中的“超时重传”就用到了定时器。当客户端向服务器发送消息时,服务器可能由于某些问题一直不回复,此时该怎么办呢?肯定不能无限的等,需要有一个最大的期限,当到达这个最大期限时,该放弃呢?还是重传呢?或者想别的解决办法,这时就用到了定时器。

内部库Timer

当然,不光要学会怎么使用内部库提供的定时器,我们还要自己手写一个定时器出来。

怎么写呢?

1、需要一个线程,不断扫描是否有任务到达时间,可以执行了。

2、需要一个数据结构,存储所有的任务。

3、还需要创建一个类,通过类的对象来描述一个任务(至少要包含做什么和时间)。

那么又出现一个问题,该使用什么数据结构呢?

用数组吗?不行,用数组每次扫描都要遍历所有任务,时间开销太大;

想想我们学过的数据结构,每次执行时间最小的,是的,没错,就是它,它就是--优先级队列!

优先级队列每次放入元素时都会更新顺序,保证时间最小的一定在最前面,因为我们每次可以执行的一定是时间最小的,之后的元素都不需要搜索,所以时间复杂度是O(1)。

代码如下:

package Thread;

import java.util.PriorityQueue;
import java.util.Timer;
import java.util.TimerTask;

class MyTimerTask implements Comparable<MyTimerTask> {
    private Runnable runnable;
    //要有一个要执行的任务
    private long time;
    //还要有一个执行任务的时间(这里是绝对时间)

    public MyTimerTask(Runnable runnable,long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

    @Override
    public int compareTo(MyTimerTask o){
        return (int)(this.time - o.time);
        //这样的写法,就是让队首元素是最小时间的值
    }

    public long getTime(){
        return time;
    }

    public Runnable getRunnable(){
        return runnable;
    }
}

class MyTimer{
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
    private Object locker = new Object();

    public void schedule(Runnable runnable,long delay){
        synchronized (locker){
            queue.offer(new MyTimerTask(runnable,delay));
            locker.notify();
        }
    }

    public MyTimer(){
        Thread t = new Thread(() -> {
            while(true){
                try{
                    synchronized (locker){
                        while(queue.isEmpty()){
                            locker.wait();
                        }
                        MyTimerTask task = queue.peek();
                        long curTime = System.currentTimeMillis();
                        if(curTime >= task.getTime()){
                            task.getRunnable().run();
                            queue.poll();
                        }
                        else{
                            locker.wait(task.getTime() - curTime);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}


public class mtime {
    public static void main(String[] args) {
        MyTimer timer = new MyTimer();
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("3000");
            }
        },3000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("2000");
            }
        },2000);

        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("1000");
            }
        },1000);

        System.out.println("程序开始执行");
    }
}

这里为什么要用wait呢?用sleep可以吗?

答案是不可以!

当我们向队列中插入元素时,会调用notify方法,这里使用wait是为了当新插入队列中的元素的时间比当前队头的元素的时间小时,就需要进行更新,重新判定一下最早的任务以及此处的等待时间。

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

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

相关文章

Linux服务器安装与配置python环境 最新linux安装python 小白教程

目录 一、下载官网的安装包 二、安装流程 三、配置软连接&#xff08;类似window系统的环境变量&#xff09; 四、可能会出现的问题&#xff1a; 1.ssl连接问题&#xff0c;下图所示&#xff1a; 一、下载官网的安装包 1.官网安装包地址&#xff1a;https://www.python.org/…

回溯算法04(leetcode93、78、90)

参考资料&#xff1a; https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html 93. 复原 IP 地址 题目描述&#xff1a; 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0…

突破空间限制,这些远程控制软件为父母送上“手把手”的教导,解决异地办公难题,出差无忧

在现代社会&#xff0c;科技的飞速发展带来了诸多便利&#xff0c;但同时也给一些年长的父母们带来了困扰。 当父母们面对智能手机电脑等高科技产品时&#xff0c;他们往往感到无所适从&#xff0c;而子女们忙于工作、学习或其他原因&#xff0c;常常无法时刻陪伴在父母身边&a…

Java版招投标管理系统源码:优化流程,提升效率,实现全方位项目管理

在现今日益竞争激烈的招标市场中&#xff0c;企业需要一款强大而灵活的招投标管理系统来优化流程、提升效率。我们的招投标管理系统正是为此而生&#xff0c;它集门户管理、立项管理、采购项目管理、公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理等多…

Android Ktor 网络请求框架

Ktor 是一个由 JetBrains 开发的用于 Kotlin 编程语言的应用框架&#xff0c;旨在创建高性能的异步服务器和客户端应用程序。由于完全基于 Kotlin 语言&#xff0c;Ktor 能够让开发者编写出简洁、可读性强且功能强大的代码&#xff0c;特别适合那些已经熟悉 Kotlin 的开发人员。…

如何利用Firebase Hosting来托管网站

文章目录 如何利用Firebase Hosting来托管网站前提条件详细步骤1. 安装 Firebase CLI2. 登录 Firebase3. 初始化 Firebase 项目4. 准备网站文件5. 部署到 Firebase6. 配置自定义域名&#xff08;可选&#xff09; 常见问题 如何利用Firebase Hosting来托管网站 以下是更详细的…

【领导力SE模型影响地图】如何分辨一个管理者有没有好的领导力? ​

影响地图是以思维导图的形式&#xff0c;在业务目标和交付物之间建立起强关联。 影响地图分为四个层级&#xff1a; 第1层级&#xff1a;目标&#xff08;Why&#xff09;- 想要达成的业务目标。 第2层级&#xff1a;利益相关者&#xff08;Who&#xff09;- 谁能够帮助达成…

基础8 探索JAVA图形编程桌面:邮件操作组件详解

在一个静谧的午后&#xff0c;卧龙和凤雏相邀来到一家古朴典雅的茶馆。茶馆内环境清幽&#xff0c;袅袅的茶香与悠扬的古筝声交织在一起&#xff0c;营造出一种宁静而祥和的氛围。 卧龙和凤雏坐在茶馆的一角&#xff0c;面前的桌子上摆放着一套精致的茶具。茶香四溢&#xff0c…

重构2:重构的原则

最近在看重构2&#xff1a;改善既有代码的设计这本书&#xff0c;对于代码重构指导非常有帮助&#xff0c;然后也是做个笔记记录下&#xff0c;以下是我阅读本书的前两章的时候整理的思维导图&#xff1a;

Leetcode3165. 不包含相邻元素的子序列的最大和(Go中的线段树分治包含多类数据使用maintain进行维护)

题目截图 题目分析 不能取相邻的&#xff0c;就是打家劫舍 然后更改某一个值就是单点更新 更新后&#xff0c;需要更新区间的值 需要注意的是&#xff0c;使用分治时需要考虑到一头一尾的问题&#xff0c;所以有4种情况&#xff08;选or不选在两个位置&#xff09; 这四种情况…

【机器学习系列】掌握随机森林:从基础原理到参数优化的全面指南

目录 目录 一、随机森林简介 (一)随机森林模型的基本原理如下&#xff1a; (二)随机森林模型的优点包括&#xff1a; (三)森林中的树的生成规则如下&#xff1a; (四)在随机森林中&#xff0c;每棵树都使用不同的训练集进行训练&#xff0c;原因如下 随机森林的分类性能&…

【Linux进程篇】Linux内核——程序地址空间的初构

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 程序地址空间回顾 我们在讲C语言的时候&#xff0c;大家应该都见过这样的空间布局图&#xff1a; 为了更好的验证不同的数据在内存中的存储位置&#xff0c;下面这段代码我们可以去实验一下&#xff1a; #include<…

眼精星和金鸣识别新增智能结构化识别,助您快速筛选和统计数据

熟悉眼精星票证识别系统或金鸣表格文字识别大师的用户都知道&#xff0c;近日&#xff0c;这二款软件同时上线了“智能结构化”功能&#xff0c;那么&#xff0c;什么是智能结构化呢&#xff1f; 准确地说&#xff0c;我们这里的智能结构化应为OCR智能结构化&#xff0c;因为它…

Docker Hub 国内镜像源配置

Docker Hub 国内镜像源配置 Docker Hub 国内镜像源是指在国内境内提供 Docker 镜像服务的镜像源。由于国际网络带宽等问题&#xff0c;国内用户下载 Docker 镜像通常速度较慢。因此&#xff0c;为了解决这个问题&#xff0c;一些国内的公司和组织提供了 Docker 镜像的国内镜像…

Java核心: 使用instrumentation

在上一篇Java核心: 注解处理器我们提到&#xff0c;通过实现AbstractProcessor&#xff0c;并调用javac -processor能够生成代码来实现特殊逻辑。不过它存在两个明显的问题: 只能新增源文件来扩展逻辑&#xff0c;无法修改现有的类或方法必须有一个单独的编译过程&#xff0c;…

【stm32/CubeMX、HAL库】嵌入式实验六:定时器(1)|定时器中断

参考&#xff1a; 【【正点原子】手把手教你学STM32CubeIDE开发】 https://www.bilibili.com/video/BV1Wp42127Cx/?p13&share_sourcecopy_web&vd_source9332b8fc5ea8d349a54c3989f6189fd3 《嵌入式系统基础与实践》刘黎明等编著&#xff0c;第九章定时器。 实验内容…

【VRIO模型】用战略模型找到你的「核心竞争力」

一个项目或企业要获得成功&#xff0c;其所拥有的资源和资源发挥的效能至关重要。那么&#xff0c;什么样的资源才能支撑项目发展的核心竞争力呢&#xff1f;VRIO是针对组织内部资源与能力&#xff0c;分析竞争优势和弱点的工具。 VRIO模型 VRIO模型是针对企业内部资源与能力…

LeetCode刷题之HOT100之三数之和

2024/5/29 天气真他妈好呀&#xff01;好天气让我舒畅&#xff0c;可惜俺今天把我养护了两三个月的栀子花花苞又整掉了一朵&#xff0c;呜呜呜&#xff01;看着它们一天天长大&#xff0c;花苞边由嫩绿泛白&#xff0c;结果被我不小心弄掉了&#xff0c;我是罪人。它们还想&…

SunoAI 智能创作歌曲神器的源码系统架构 前后端分离 附带完整的源代码包以及安装搭建教程

系统概述 SunoAI 智能创作歌曲神器的源码架构是基于先进的技术理念构建而成。前端采用了现代化的用户界面设计&#xff0c;为用户提供直观、友好的操作环境。后端则运用高效的算法和强大的处理能力&#xff0c;确保歌曲创作的准确性和高质量。 代码示例 系统特色功能模块 1.智…

Vue3 - 实现一个雨水滴落的动画效果

在 Vue 3 中实现一个雨水滴落的动画效果,可以使用 HTML5 的 <canvas> 元素和 JavaScript 来绘制和控制动画。 以下是一个实现雨水滴落效果的示例: 创建一个 Vue 3 项目 首先,确保你已经创建了一个 Vue 3 项目。如果还没有,可以使用 Vue CLI 来创建: vue create r…