当前位置: 首页 > news >正文

做网页兼职网站排名优化关键词公司

做网页兼职网站,排名优化关键词公司,nodejs做视频网站,wordpress搭建知识库目录 一. 什么是“定时器” 二. 标准库的定时器 三. 定时器的实现 MyTimer 3.1 分析思路 1. 创建执行任务的类。 2. 管理任务 3. 执行任务 3.2 线程安全问题 四. 拓展 一. 什么是“定时器” 定时器是软件开发中的一个重要组件,类似于一个“闹钟”&#xff0…

目录

一. 什么是“定时器”

二. 标准库的定时器 

三. 定时器的实现 MyTimer

3.1 分析思路

1. 创建执行任务的类。

 2. 管理任务

3. 执行任务

3.2 线程安全问题

四. 拓展


一. 什么是“定时器”

   定时器是软件开发中的一个重要组件,类似于一个“闹钟”,达到一个设定的时间之后,就执行某个指定好的代码。

   定时器是一种实际开发中非常常用的组件:比如网络通信中,如果对方 500ms 内没有返回数据,则断开连接尝试重连;比如一个 Map,希望里面的某个 key 在 3s 之后过期(自动删除)
   类似于这样的场景就需要用到定时器。

二. 标准库的定时器 

   Timer类是一个线程安全的工具类,用于在指定的时间后执行或定期执行任务。它基于绝对时间,而不是基于固定时间间隔调度任务。Timer类比较简单,适用于简单的定时任务,但不适合处理复杂的调度需求。(ScheduleExecutorService 提供了更灵活的线程管理功能,适用于复杂的调度场景,并且能够处理异常)

  • 标准库中(java.util.Timer ),Timer 类的核心方法为 schedule
  • schedule 包含两个参数,第一个参数指定即将要执行的任务代码,第二个参数指定多长时间之后执行(单位为毫秒)
import java.util.Timer;
import java.util.TimerTask;public class Timer1 {public static void main(String[] args) throws InterruptedException {Timer timer1 = new Timer();timer1.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello delay"+" " +1000);}},1000);timer1.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello delay"+" " +2000);}},2000);timer1.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello delay"+" " +3000);}},3000);// 等待提交的任务执行完毕后,调用 cancel 便可结束进程Thread.sleep(4000);timer1.cancel();}
}

三. 定时器的实现 MyTimer

3.1 分析思路

对于定时器来说:

  1. 创建描述一个要执行的任务(任务内容 + 执行任务时间)的类
  2. 管理多个任务,通过一定的数据结构,把多个任务存起来
  3. 有专门的线程,执行这里的任务
1. 创建执行任务的类。

   我们在调用 schedule 时,传的是延迟时间 “delay” 值。但是,描述任务时,不太建议使用 delay

表示,最好使用 “绝对时间”(时间戳)来表示~~

public class MyTimerTask implements Comparable<MyTimerTask>{//此处这里的 time,通过毫秒时间戳,表示这个任务具体啥时候执行private long time;private Runnable runnable;public  MyTimerTask(Runnable runnable,long delay){this.time = System.currentTimeMillis() + delay;this.runnable = runnable;}public void run(){runnable.run();}public long getTime(){return time;}@Overridepublic int compareTo(MyTimerTask o) {//比如,当前时间是 10:30,任务时间是 12:00,不应该执行//如果当前时间是 10:30,任务时间是 10:29,应该执行//谁减去谁,可以通过实验判断return (int) (this.time - o.time);}
}
 2. 管理任务

   使用 List 管理任务,不是一个好选择——因为后续执行列表中的任务时,就需要依次遍历每个元素;执行完毕后,还需要把对应的任务从 List 中删除掉。

   我们需要按照时间来执行这里的任务。只要能够确定所有任务中,时间最早的任务,判定它是否到该执行的时间即可。如果时间最早的任务还没到执行时间,其他任务更不可能到时间了。因此,我们使用堆数据结构(涉及到队列中的元素排序时,考虑堆)——PriorityQueue<MyTimerTask>(优先级队列管理元素时,需要有比较方法,才能排序存储。因此,在实现 MyTimerTask 类时,要继承 Comparable<MyTimerTask> 接口,重写 compareTo比较方法)

3. 执行任务

   当创建 MyTimer 对象,调用无参构造方法时,便创建一个线程,循环执行从队列中取出任务的操作:取出队列中 “绝对时间” 最早的任务——如果当前时间 >= 此任务的时间(已经到达此任务的执行时间),便可调用run方法执行,执行完毕后从队列中删除; 如果当前时间 < 此任务的时间(没到此任务的执行时间),则继续执行循环。(所以,在实现 MyTimerTask 类时,要有 run方法 和 getTime方法)

   除此之外 ,还需要有 schedule 方法添加任务。

import java.util.PriorityQueue;public class MyTimer {private final PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();public MyTimer() {Thread t = new Thread(() -> {while (true){if(queue.isEmpty()){ continue;}MyTimerTask task = queue.peek();//判断是否满足执行条件if (System.currentTimeMillis() >= task.getTime()) {task.run();//执行完后,便从队列中删除queue.poll();}else{continue;}}});t.start();}public void schedule(Runnable runnable, long delay) {MyTimerTask task = new MyTimerTask(runnable, delay);queue.offer(task);}
}
3.2 线程安全问题

   当前这个代码,是没有考虑线程安全问题的。

   PriorityQueue 这个类自身,是非线程安全的,并且又是多个线程来进行操作,一定存在线程安全问题的风险。因此,要在涉及队列相关操作的地方加锁

import java.util.PriorityQueue;public class MyTimer {private final PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();private final Object locker = new Object();public MyTimer() {Thread t = new Thread(() -> {while (true){synchronized(locker){if(queue.isEmpty()){ continue;}MyTimerTask task = queue.peek();if (System.currentTimeMillis() >= task.getTime()) {task.run();queue.poll();}else{continue;}}}});t.start();}public void schedule(Runnable runnable, long delay) {synchronized(locker){MyTimerTask task = new MyTimerTask(runnable, delay);queue.offer(task);}}
}

   但是,加完锁以后,又出现了线程安全问题。 

1)初始情况下,如果队列中,没有任何元素。此时,就会在短时间内执行大量循环,这样的执行是没有意义的,导致“线程饿死”。

   因此,我们需要添加 wait 和 notify 机制:队列为空时,进行等待;添加任务时,就唤醒线程。


 2)假设队列中,已经包含元素了,并且当前时间是 10:45,任务时间 12:00(类似于,我定了12:00的闹钟,现在是 10:45)。在判断任务是否满足执行条件时,不满足就会一直循环(相当于每隔一会儿就看一眼闹钟),这样无意义的执行就一直占用着cpu资源,导致 “线程饿死”。

   因此,我们需要添加一个有等待期限的 wait(等待 1h15min 就会执行),当到达任务执行时间,wait 就结束了。如果在等待过程中,又再次调用 schedule 方法,也会唤醒这里的 wait,进行新一轮的判断。


 线程安全版:

import java.util.PriorityQueue;public class MyTimer {private final PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();private final Object locker = new Object();public MyTimer() {Thread t = new Thread(() -> {try {while (true) {synchronized (locker) {while (queue.isEmpty()) {//如果还没添加任务,会不断循环执行判断,出现线程饿死。//continue;//因此,使用wait等待,当添加任务后唤醒locker.wait();}MyTimerTask task = queue.peek();if (System.currentTimeMillis() >= task.getTime()) {task.run();queue.poll();} else {//如果还没到任务执行时间,依旧不断循环判断,出现线程饿死。//continue;//因此,使用有等待期限的 wait,计算执行的时间与当前时间的差值//当添加新的任务后,wait 被唤醒,再进行新的判断locker.wait(task.getTime() - System.currentTimeMillis());}}}} catch (InterruptedException e) {e.printStackTrace();}});t.start();}public void schedule(Runnable runnable, long delay) {synchronized (locker){MyTimerTask task = new MyTimerTask(runnable, delay);queue.offer(task);// 唤醒 waitlocker.notify();}}
}

 * 能否将第二处的 wait 改为 sleep 呢? ——不能!!

 不应该使用sleep,可能存在以下情况:

     1)在 sleep 阻塞1h15min 的过程中,新来了一个时间更早的任务,比如 11:30 要执行。如果使用 wait ,每次新来的任务,都会把 wait 唤醒,重新设定 wait 的等待时间。而 sleep 不会被唤醒,依旧在阻塞着.....

     2)sleep 休眠的时候,不会释放锁。因此,在休眠的时候就是“抱着锁”,其他人想拿锁就拿不到了。


 * PriorityQueue 是线程不安全的类,能否使用 PriorityBlockingQueue 线程安全的阻塞队列呢?——不能!! 

   如果使用线程安全的队列,会导致代码中从 一把锁 变成 两把锁,很容易出现死锁的情况,比如持有和请求的情况(并非100%一定出现,但是需要程序员精心控制加锁顺序,使得编写代码的复杂度提高了。如果通篇代码 只有一把锁,就能更容易地解决问题)


 * 如果某个任务的执行时间过长怎么办? 

   此处只有一个线程,串行执行每一个任务。如果某个任务执行时间过长,可能会影响到定时器的准确性(特别是对于周期性任务),使后续的任务被延迟——解决方案,多创建几个这样的工作线程。

四. 拓展

   业界实现定时器,除了基于优先级队列的方式之外,还有一种经典的实现方式——“时间轮”

   “时间轮” 是一种设计巧妙的数据结构,通常用于高效处理大量的定时任务。它是定时器任务调度的一种优化方案,尤其在需要调度大量短任务的场景中非常有效。时间轮的概念类似于钟表,它将时间划分为固定数量的槽位,每个槽位对应一个时间间隔,用于存储该时间间隔内需要执行的任务。

   (这只是简单介绍,不做过多讨论,可自行查阅~~)

   定时器特别重要,也特别常用,尤其是后端开发中,和 “阻塞队列” 类似,也会有专门服务器,用来在分布式系统中实现定时器这样的效果。

  • hashmap --> redis
  • 阻塞队列 --> 消息队列
  • 定时器 --> 定时任务

文章转载自:
http://wanjiaprepositional.kjrp.cn
http://wanjiadivulgate.kjrp.cn
http://wanjiascrimp.kjrp.cn
http://wanjiaequicaloric.kjrp.cn
http://wanjiaobeisance.kjrp.cn
http://wanjiairretraceable.kjrp.cn
http://wanjiaturfan.kjrp.cn
http://wanjiasematic.kjrp.cn
http://wanjiaimprovvisatore.kjrp.cn
http://wanjiaglomera.kjrp.cn
http://wanjiamica.kjrp.cn
http://wanjiaunfit.kjrp.cn
http://wanjiaescarpmetnt.kjrp.cn
http://wanjiametacompilation.kjrp.cn
http://wanjiahektostere.kjrp.cn
http://wanjiavoltammeter.kjrp.cn
http://wanjiaironware.kjrp.cn
http://wanjiacommunicatee.kjrp.cn
http://wanjiaagalite.kjrp.cn
http://wanjiacitroen.kjrp.cn
http://wanjiafelonious.kjrp.cn
http://wanjianephrolith.kjrp.cn
http://wanjiainterrogee.kjrp.cn
http://wanjiasclerema.kjrp.cn
http://wanjiaorchardman.kjrp.cn
http://wanjiamehetabel.kjrp.cn
http://wanjiacoach.kjrp.cn
http://wanjiaanhematosis.kjrp.cn
http://wanjiajanet.kjrp.cn
http://wanjiasemispherical.kjrp.cn
http://wanjiaoversail.kjrp.cn
http://wanjiater.kjrp.cn
http://wanjiawashable.kjrp.cn
http://wanjiascirrhoid.kjrp.cn
http://wanjiajotunnheim.kjrp.cn
http://wanjiaagamemnon.kjrp.cn
http://wanjiarouseabout.kjrp.cn
http://wanjiapenuche.kjrp.cn
http://wanjiadispauperization.kjrp.cn
http://wanjiareload.kjrp.cn
http://wanjiaisis.kjrp.cn
http://wanjiaanteriority.kjrp.cn
http://wanjiaconvulse.kjrp.cn
http://wanjiapapillectomy.kjrp.cn
http://wanjiagatefold.kjrp.cn
http://wanjiasubprefect.kjrp.cn
http://wanjiaunintelligent.kjrp.cn
http://wanjiaforejudge.kjrp.cn
http://wanjiaketose.kjrp.cn
http://wanjiatheine.kjrp.cn
http://wanjiabridgeboard.kjrp.cn
http://wanjiasaxifrage.kjrp.cn
http://wanjiaadmittance.kjrp.cn
http://wanjiaoomingmack.kjrp.cn
http://wanjiaproudhearted.kjrp.cn
http://wanjianirvana.kjrp.cn
http://wanjiafantastico.kjrp.cn
http://wanjiaavowably.kjrp.cn
http://wanjianerine.kjrp.cn
http://wanjiapolystyle.kjrp.cn
http://wanjiaafips.kjrp.cn
http://wanjiaclan.kjrp.cn
http://wanjiaodeon.kjrp.cn
http://wanjiasakellarides.kjrp.cn
http://wanjiaascensive.kjrp.cn
http://wanjiaprosodic.kjrp.cn
http://wanjiacontainerboard.kjrp.cn
http://wanjiaentrepot.kjrp.cn
http://wanjialogginess.kjrp.cn
http://wanjiagamahuche.kjrp.cn
http://wanjiavolumeter.kjrp.cn
http://wanjiaherbarize.kjrp.cn
http://wanjiarecast.kjrp.cn
http://wanjiaparsonage.kjrp.cn
http://wanjiamicrosequencer.kjrp.cn
http://wanjiabiosatellite.kjrp.cn
http://wanjiaanapestic.kjrp.cn
http://wanjiascreech.kjrp.cn
http://wanjiabiopoesis.kjrp.cn
http://wanjiamatador.kjrp.cn
http://www.15wanjia.com/news/127348.html

相关文章:

  • 北京保安公司seo的工具有哪些
  • 100个最佳市场营销案例北京seo
  • 朝阳区网站开发公司产品经理培训哪个机构好
  • 英文购物网站模板下载游戏推广怎么快速拉人
  • 做网站常用的cssseo站长优化工具
  • 手机网站打开速度网址搜索引擎入口
  • 私人彩票网站做几年牢湖南中高风险地区
  • 网站需要网监备案美工培训
  • 怎样设计自己的网站短视频seo排名系统
  • wordpress 环境搭建关键词优化包含
  • 做网站运营有趣吗怎样做网站推广啊
  • 企业门户网站功能商品推广
  • 专业网站制作技术永久域名查询
  • 网站打开空白 重启iis就好了网络营销服务商有哪些
  • 湖南网站建设公司 尖端磐石网络在哪里找专业推广团队
  • 黄山网站建设方案2022年十大流行语
  • 上海网站建设微信开发深圳seo优化排名
  • html语言做的网站和asp的区别水果店推广营销方案
  • 商城网站建设开发公司网站推广优化教程
  • 本地上海集团网站建设seo搜索引擎优化师
  • 罗岗网站建设公司谷歌google官方网站
  • 湛江做网站哪家好百度提问登陆入口
  • 网站显示乱码怎么办啊关键词优化案例
  • 一条龙平台seo兼职接单平台
  • 上海公司注册查名官网郑州seo技术服务
  • html5做图书馆网站优化网站性能监测
  • 贵州国高建设工程有限公司 网站2022年十大网络流行语发布
  • 网站 手机 微信 app手机优化大师为什么扣钱
  • 做动态网站的步骤潍坊seo培训
  • 做网站 大文件免费网站怎么注册