Timer执行过程

Java定时器Timer的使用 介绍Java定时器Timer的使用 阅读详情

Timer 定时器执行过程:Timer TimerTask TimerQueue

Timer是一个单线程 + 最小堆 + 不断轮询

 

Timer time=newTimer();

n  调用构造方法创建timer类

public Timer(){

this("Timer-"+ serialNumber());

}

private final static AtomicIntegernextSerialNumber = new AtomicInteger(0);

private static int serialNumber() {

return nextSerialNumber.getAndIncrement();

}

This方法: 这个name是Timer-0

public Timer(String name) {

thread.setName(name);

thread.start();

}

对name设置值

public final void setName(String name) {

checkAccess();

this.name = name.toCharArray();

}

checkAccess();

这个是权限控制

publicfinalvoid checkAccess() {

SecurityManager security =System.getSecurityManager();

if (security != null) {

security.checkAccess(this);

}

}

 

SecurityManager  对运行的java代码进行权限控制,防止恶意代码的运行

开启线程:

thread.start();  这个运行的是timerThread 的run方法

 

这里先略过,

time.schedule(new TaskTest(), 1000);  定时类设置任务和每次时间间隔执行的时间

 

public void schedule(TimerTask task, long delay){

if (delay < 0)

throw new IllegalArgumentException("Negativedelay.");

sched(task, System.currentTimeMillis()+delay, 0);

}

//初始化task、 task 执行任务  time时间period 间隔

privatevoid sched(TimerTask task, long time, long  period) {

if (time < 0)

thrownew IllegalArgumentException("Illegal executiontime.");

 

// Constrain value of periodsufficiently to prevent numeric

// overflow while still beingeffectively infinitely large.

if (Math.abs(period) >(Long.MAX_VALUE >> 1))   间隔的绝对值 大于 LONG的最大值右移动一位  Long.MAX_VALUE   =9223372036854775807

Long.MAX_VALUE >> 1 =4611686018427387903

period >>= 1;      period右移一位并重新赋值给自己

 

 

 这里插一下开始的时候创建了thread   TimerThread thread = new TimerThread(queue);

                           Queue    private TimerTask[] queue = newTimerTask[128];

synchronized(queue) {

if (!thread.newTasksMayBeScheduled)     判断 线程的newTasksMayBeScheduled 这个值是true还是false

thrownew IllegalStateException("Timer alreadycancelled.");如果是true 就报错

 

 

 

synchronized(task.lock) {

if (task.state != TimerTask.VIRGIN)   判断线程状态 task。State 初始是0  TimerTask.VIRGIN 初始也是0,如果初始状态不等就报错

thrownew IllegalStateException("Task already scheduledor cancelled");

task.nextExecutionTime = time; 任务的下一个执行时间是time

task.period = period;   间隔是period

task.state = TimerTask.SCHEDULED;  TimerTask.SCHEDULED =1

}

queue.add(task);  把任务加入到队列

 

 这里插入一下queue的方法add

void add(TimerTask task) {

       // Grow backing store if necessary

       if (size + 1 == queue.length) size 初始化是0  ,如果size+1是现在队列的长度就默认扩容2倍

           queue = Arrays.copyOf(queue, 2*queue.length);

 

       queue[++size] = task; 加入队列  queue是TimerTask数组,默认初始化128内存

 

 

       fixUp(size);

这里插入fixup   比较队列中现在这个任务和上一个任务的执行时间

privatevoidfixUp(int k) {

        while (k> 1) {

            int j =k >> 1;  右移动是减少 2>>1 变成1

            if (queue[j].nextExecutionTime<= queue[k].nextExecutionTime)

                break;

            TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] =tmp;

            k = j;  这里把k减少

        }

    }

 

    }

if (queue.getMin() == task)  如果队列中的  和现在这个task一样 就唤醒其他等待线程

 

getMIn=queue【1】; 

queue.notify();

}

}

、task的执行:

 

publicvoidrun() {

        try {

            mainLoop();

        } finally {

            // Someonekilled this Thread, behave as if Timer cancelled

            synchronized(queue) {

                newTasksMayBeScheduled = false;

                queue.clear();  // Eliminate obsoletereferences

            }

        }

    }

 

   privatevoidmainLoop() {

        while (true) {  //轮循环

            try {

                TimerTask task;

                booleantaskFired;

                synchronized(queue) {

                    // Wait forqueue to become non-empty

                    while (queue.isEmpty()&& newTasksMayBeScheduled)   如果队列是空的就进入等待

                        queue.wait();

                    if (queue.isEmpty())

                        break; //Queue is empty and will forever remain; die

 

                    // Queuenonempty; look at first evt and do the right thing

                    longcurrentTime, executionTime;

                    task = queue.getMin();

                    synchronized(task.lock) {

                        if(task.state == TimerTask.CANCELLED) {

                            queue.removeMin();

                            continue;  // No action required, pollqueue again

                        }

                        currentTime = System.currentTimeMillis();

                        executionTime = task.nextExecutionTime;

                        if(taskFired = (executionTime<=currentTime)) { //比较执行时间和系统时间

                            if(task.period == 0) { //Non-repeating, remove

                                queue.removeMin();

                                task.state =TimerTask.EXECUTED;

                            } else { //Repeating task, reschedule

                                queue.rescheduleMin(

                                  task.period<0? currentTime   - task.period

                                               : executionTime + task.period);  //这里计算下一次的执行时间,轮询的时候比较下一次的执行时间,如果时间不对就不执行  这里有个问题,就是为什么动态循环都是只有下下一次才能改变这个时间间隔,而不是下一次,因为这次就决定了下次时间的决定。所以timer没办法改变下一次的执行时间,但是可以改变下下次的执行,那么这里我是不是可以重写这个函数,把执行时间可以从外部传进去。

                            }

                        }

                    }

                    if(!taskFired) // Task hasn't yet fired; wait

                        queue.wait(executionTime- currentTime);

                }

                if(taskFired)  // Task fired;run it, holding no locks

                    task.run();

            } catch(InterruptedExceptione) {

            }

        }

    }

C# timer添加事件处理 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Sy... 阅读详情

相关推荐

KALI虚拟机挂代理教程

需要你本地挂了代理,然后通过虚拟机连接本机代理端口,不说废话了,直接说怎么做了。 1.查看选项设置中自己的小飞机的本地端口是多少:(默认是1080) 2.本机win+r打开cmd,输入ipconfig查看本地ip,我的本地ip是192.168.0.107: 2.打开kali虚拟机,编辑ProxyChains配置文件: vi /etc/proxychains.conf 3.在文件末尾的ProxyList中添加物理机本地ip和1080端口作为代理地址: 4.保存并退出即可: esc :wq 回车 5.

qq_34853514的博客 3万+

Timer 和TimerTask分析

Timer 定时器使用举例大家都知道Timer 可以用来做定时任务, 使用举例,定时5s执行sendPing()逻辑:Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { sen

amyli的专栏 2141

在macOS上使用GitHub的超详细指南

GitHub:免费的远程仓库,可用来托管自己的开源项目。它利用了Git强大的克隆和分支功能,让我们参与别人的开源项目和让别人参与自己的开源项目变得简单高效。

Mars的博客 3391

Timer 一次性定时任务的简单使用和取消

绑定具有唯一性的id,使用场景中是具有唯一性的参数,例如教室id,根据需求是否要取消指定定时任务,若需要通过id来获取所取得的定时任务,执行取消命令;配置静态map集合(或hashTable)两个,一个用于记录定时时间,一个用于存放定时任务Timer;自定义自身执行类继承TimerTask,添加所需参数于其中,在run方法中调用所需参数;

weixin_62752892的博客 984

基于深度学习YOLOv8的花卉检测与识别系统(附完整资源+PySide6界面+训练代码)

通过本项目,我们成功实现了基于YOLOv8的花卉检测与识别系统,涵盖了数据预处理、模型训练、推理与实时检测、以及GUI界面的实现。YOLOv8在花卉检测中的高效性和准确性为实际应用提供了强有力的支持。

斌擎科技 716

YOLOv10涨点改进:SPPF原创自研创新 | SPPF创新结构,重新设计全局平均池化层和全局最大池化层,增强全局视角信息和不同尺度大小的特征

SPPF原创自研创新

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 2086

Timer定时任务

1. kingshard的应用场景 现在很多互联网公司还是在大量使用MySQL来存储各种类型的关系型数据。随着访问量和数据量的增长,开发者不得不考虑一些MySQL相关的新问题: 读写分离问题。由于前端应用访问量增加,单台MySQL不足以支撑整个系统的写入和查询操作。这时候,我们不得不将一些耗时的查询操作分散到多个slave上。 单表容量问题。如果在系统设计之初,没有考

我是Alvin家鸡鸭鱼的小米米 1154

OWASP-ZAP扫描器的使用

目录 OWASP-ZAP 更新 代理 目录扫描 主动扫描(Active Scan) 扫描结果 生成报告 OWASP-ZAP OWASP Zed攻击代理(ZAP)是世界上最受欢迎的免费安全审计工具之一,由数百名国际志愿者积极维护。它可以帮助你在开发和测试应用程序时自动查找Web应用程序中的安全漏洞。 也可以说ZAP是一个中间人代理。它能够获取你对Web应用程序发出的所有请求以...

谢公子的博客 2万+

thread --- detach()的使用

thread --- detach()

shunlu5586的博客 6314

高通开发系列 - System之FOTA/DFOTA包制作和升级

高通开发系列 - System之FOTA/DFOTA包制作和升级

fulinux的博客 4222

Python中的字典(Dictionary)学习

上一章节,我们学习了列表(List) 和 元组(tuple) 来表示有序集合。而我们在讲列表(list)的时候,我们用了列表(list) 来存储用户的姓名。那么如果我们为了方便联系这些童鞋,要把电话号码也添加进去,该怎么做呢?但是这样很不方便,我们把电话号码记录下来,就是为了有什么事能及时联系上这些童鞋。如果用列表来存储这些,列表越长,我们查找起来耗时就越长。

热情、奔放、快乐编程! 503

Timer的执行过程

Timer 定时器原理:Timer 类:if (time &lt; 0)thrownew IllegalArgumentException("Illegal executiontime."); // Constrain value of periodsufficiently to prevent numeric// overflow while still beingeffectively inf...

jiangbinbin的博客 541

大数据预测分析:精准把握市场趋势

传统市场预测多依赖经验判断(比如“去年卖了1000件,今年加20%”)或小数据统计(比如用近6个月的销量做线性回归)。而大数据预测分析是:利用海量结构化+非结构化数据(销售、用户、社交媒体、天气等),通过机器学习/深度学习模型,挖掘数据中的关联关系与趋势规律,实现对未来市场走势的精准预测。更全面:覆盖内部(企业数据)+外部(行业、环境数据)的全维度数据;更精准:用算法替代人工,避免主观偏差;更实时:支持分钟级/小时级的实时预测(比如直播带货的销量预测)。错误做法。

AI智能探索者的博客 1024

systemtap执行过程中报probe timer.profile registration error

probe timer.profile registration error 今天在执行火焰图的过程中,代码报错,probe timer.profile registration error 经过查询、分析可能是在该平台该函数是不安全、不共享的。 将 probe timer.profile { 用该代码替换即可 probe perf.sw.cpu_clock !, timer.profile { ...

weixin_34379433的博客 309

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android延时执行Timer类的使用

Android定时控制类一般使用Timer即可。初使化Timer类new Timer(),执行延时事件new TimerTask(),timerTask 第一个参数为要执行的事件,第二个参数为延迟多久执行,第三个参数为每次执行的间隔时间,可选。一个Timer类实例可以执行多个TimerTask事件,但一旦运行起来便会一直执行下去,直到timer.cancel()事件,结束整个timer进程。TimerTask 无法更新主线程上的UI控件内容,只能借用Handler在不同线程中传递信息。

曲幽 1347

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java中的timer类

使用java中的Timer实现任务调度的核心类是Timer和TimerTask。其中Timer负责设定TimerTask的起始与结束时间。使用者只需要创建一个TimerTask的继承类,实现自己的run方法,然后将其丢给Timer去执行。(如下实例:) package com.yc.quartz.example; import java.util.Timer; impor

技术分享 4766

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

在java.lang.Timer为非守护线程的情况下,加入到TimerTask的任务执行完毕了,Timer线程仍在继续运行的原因

问题引入: 假设当前时间为2019-03-13 22:10:00 ,定义任务A在3分钟后执行,任务B在5分钟后执行,我们将A和B加入至Timer中,根据Timer中TaskQueue顺序启动任务的原则,8分钟后任务A和任务B都会执行完毕。问题来了,明明任务全部执行完毕了,为什么Timer线程仍在继续 执行,就仿佛停不下来了呢? 首先,我们来看看Timer的构造函数 public Ti...

爱喝咖啡的程序员的博客 1071

java.util.timer_java.util.Timer浅析

Timer是JDK中的定时调度类,主要用来定时触发任务: 用法:Timer是调度控制器,TimerTask是可调度的任务:1: import java.util.Date;2: import java.util.TimerTask;3:4: public class PlainTimerTask extends TimerTask {5:6: @Override7: public...

weixin_39551611的博客 212

java再次设置Timer的schedule

Timer定时器启动以后需要更改定时器的执行频率,可以使用如下方法: package test; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import common.util.DateTimeFormatUtil; import common.util.P; public cla

ljj2312的专栏 2974

c语言多线程和timer区别,C# 多线程之通过Timer开启线程的例子

usingSystem;usingSystem.Threading;/*这是一个关于 timer开启多线程的一个例子* 1.Timer 的tick事件触发系统内置委托TimerCallback委托。而此委托会触发一个新的线程 。此线程中需要完成的具体的工作写成一个静态方法。作为参数传递给这个委托。* 2.如果是用Timer触发的线程会自动开始不需要用到.Start()来启动* 3.如果没有使用线程...

weixin_35756690的博客 722

Timer机制源码浅析

作者:点先生 时间:2019.3.27 逼逼两句 Q:定时、延时任务有几种方式可以实现? A:Handler、Timer、ScheduledThreadPool、AlarmManager Handler机制大家应该都烂熟于心了,今天我来讲讲Timer这个不常被问到的定时器。 改日再说线程池,预计是周日。 Timer机制包含了四个主要核心类:Timer,TaskQueue,TimerThread...

weixin_34162629的博客 127

jdk源码之定时器Timer源码解析

定时器Timer源码解析 一 Timer 1、Timer Timer较之Quartz结构相对简单,其原理更容易动,并且两个会有相似之处,可以在了解Timer之后在看Quartz可能会相对容易通透一点,在Quartz之前先了解一下Timer定时器,以下是JDK Api中的介绍: 线程调度任务以供将来在后台线程中执行的功能。 任务可以安排一次执行,或定期重复执行。 对应于每个Timer对象是单个后台线程,用于依次执行所有定时器的所有任务。 计时器任务应该快速完成。 如果一个定时器任务需要花费很多时间来完成,

drop616的博客 893

Timer 填坑指南 ,发现 Google 的 Bug啦!

在开发过程中经常用到 Timer,用于隔一段时间重复执行相应的任务,用起来也很简单,相信聪明的你肯定会用了,没错简单的如下: Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { //do something } }, 0,

johndon_forever的博客 288

Timer的工作原理

从源码角度理解Timer的工作原理

songyunzu的博客 3184

java timer类的功能,Java:利用java Timer类实现定时执行任务的功能

一、概述在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类。其中Timer是用来在一个后台线程按指定的计划来执行指定的任务。TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务,具体要执行的代码写在TimerTask需要被实现的run方法中。二、先看一个最简单的例子我们通过代码来说明importjava.text.SimpleDateForma...

weixin_30753697的博客 224

java timer 多个任务_Java循环调用多个timer实现定时任务

通常在使用java实现定时任务时,有两种方法,一种是spring中的schedule(cron = " */5 * * * ?"),另一种就是java中的timer,timer+TimerTask配合实现,这里附上Timer对象的一些常用apiTimer()                 创建-个新计时器。Timer(boolean isDaemon)        创建一个新计时器, 可...

weixin_42647395的博客 1499
上一篇: 递归调用遇到的问题
下一篇: jvm
蓝猫_虹
博客等级 码龄12年 49粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值