定时任务实现

1、定时任务概述

定时任务是一种自动化执行特定操作的方式,可以根据预定的时间、日期或间隔周期性地执行某些任务。

定时任务的作用?

自动化任务执行:定时任务能够在预定的时间触发执行某些任务,无需人工干预。这对于需要定期执行的重复性任务非常有效,例如数据备份、统计报表生成、系统维护等。
提高效率和准确性:通过定时任务,可以在特定的时间段内自动执行任务,避免了人工操作的疏忽和错误。这样可以提高任务的执行效率和准确性,并降低因人为原因导致的错误风险。
节省时间和资源:定时任务可以代替人工手动执行的操作,节省了大量人力资源和时间成本。同时,它也可以合理分配系统资源,避免任务集中导致的系统负载过高。
异步执行:定时任务可以在后台异步执行,不会阻塞用户的其他操作。这对于需要执行耗时较长的任务或需要长时间运行的操作非常有用,可以提高系统的响应速度和用户体验。

2、定时任务的常见几种方式

1)线程类实现定时任务:比如Thread、Runnable、Callable等线程类都可以实现定时任务

2)Timer/TimerTask:Java提供了java.util.Timer和java.util.TimerTask类,可以用于创建定时任务。通过创建一个Timer对象,并调用其schedule()方法,可以指定任务的执行时间和执行间隔。然后,创建一个继承自TimerTask的子类,实现具体的任务逻辑,并在run()方法中定义需要执行的代码。最后,将该任务对象通过Timer的schedule()方法进行调度即可。

3)ScheduledExecutorService:Java提供了java.util.concurrent.ScheduledExecutorService接口,是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。可以用于创建定时任务。通过调用ScheduledExecutorService的scheduleAtFixedRate()或scheduleWithFixedDelay()方法,可以指定任务的执行时间和执行间隔。然后,创建一个实现了Runnable接口的类,实现具体的任务逻辑,并在run()方法中定义需要执行的代码。最后,将该任务对象提交给ScheduledExecutorService进行调度即可。

4)@Scheduled注解:这个是Spring框架所提供的,通过在方法上添加@Scheduled注解,并设置相应的时间表达式,就可以让方法按照指定的时间间隔自动执行。

3、timer实现定时任务

3.1)timer实现定时任务案例

        // 创建一个Timer对象  Timer timer = new Timer();创建一个TimerTask对象,并重写其run方法  TimerTask timerTask = new TimerTask() {int count = 0; @Overridepublic void run() {//执行定时任务的逻辑count++;  System.out.println("定时任务执行次数: " + count);  // 当count等于5时,打印出定时任务执行完毕,并调用timer.cancel()取消定时任务  if (count == 5) {  System.out.println("定时任务执行完毕");  timer.cancel();  }  }};// 延迟1秒后开始执行定时任务,每隔2秒执行一次  timer.schedule(task, 1000, 2000);  

以上案例代表延迟1秒后执行输出次数,每2秒执行1次,输出如下:

定时任务执行次数: 1

定时任务执行次数: 2

定时任务执行次数: 3

定时任务执行次数: 4

定时任务执行次数: 5

定时任务执行完毕

3.2)Timer的常用方法

schedule(TimerTask task, Date time):在指定的时间执行任务。参数task是要执行的任务,参数time是任务的执行时间。
schedule(TimerTask task, long delay):在指定的延迟时间后执行任务。参数task是要执行的任务,参数delay是任务的延迟时间(单位为毫秒)。
schedule(TimerTask task, long delay, long period):在指定的延迟时间后开始执行任务,并按照指定的周期重复执行。参数task是要执行的任务,参数delay是任务的延迟时间(单位为毫秒),参数period是任务的执行周期(单位为毫秒)。
scheduleAtFixedRate(TimerTask task, long delay, long period):在指定的延迟时间后开始执行任务,并以固定的速率重复执行。参数task是要执行的任务,参数delay是任务的延迟时间(单位为毫秒),参数period是任务的执行周期(单位为毫秒)。该方法会尽量保持每次任务执行的时间间隔固定。
cancel():取消所有已安排的任务。调用该方法后,Timer将不再接受新任务,并尝试终止当前正在执行的任务。

3.3)timer的优缺点

优点:JDK自带的,简单易用
缺点
对系统时间敏感:Timer类的任务调度是基于绝对时间的,而不是相对时间。这意味着对系统时间的改变非常敏感,当系统时间发生变化时,可能导致任务执行时间的误差。
单线程执行:Timer类内部使用单个线程来执行所有的定时任务。如果某个任务执行时间过长,会影响其他任务的执行,可能导致任务被延迟。
错误处理能力有限:Timer类的错误处理能力较弱。如果定时任务出现异常并抛出未捕获的异常,Timer类将会停止所有任务的执行。
任务的无法持久化:当应用程序关闭或重启时,Timer 中已经调度的任务会丢失
不适合高并发场景:由于Timer类使用单个线程执行所有任务,不适合在高并发环境下使用。当任务过多或任务执行时间较长时,会影响整体性能和响应性。

3.4)timer的异常捕获

Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,它会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。

例如:

        Timer timer = new Timer();TimerTask timerTask = new TimerTask() {@Overridepublic void run() {int x = 1/0;System.out.println("执行定时任务");}};timer.scheduleAtFixedRate(timerTask, 5 * 1000, 10 * 1000);

执行结果如下:

 

因此如果要防止使用timer因未捕获的异常而使得任务停止,可以在重写run方法内进行异常捕获,修改代码如下:

        Timer timer = new Timer();TimerTask timerTask = new TimerTask() {@Overridepublic void run() {try{System.out.println("定时任务开始");int x = 1/0;System.out.println("执行定时任务");}catch(Exception e){System.out.println("异常捕获");}}};

 运行结果如下:

3.5)timer任务传入参数实现

public class task extends TimerTask{private int x;public task(int x) {this.x = x;}@Overridepublic void run() {//执行定时任务的逻辑System.out.println(x);}public static void main(String[] args) {Timer timer = new Timer();timer.scheduleAtFixedRate(new task(3), 5 * 1000, 10 * 1000);}}

3.6)Timer和TimerTask之间的联系和区别

1) 定义与功能

  1. TimerTask类

    • TimerTask是一个抽象类,它实现了Runnable接口的run()方法。
    • 主要功能:定义要执行的具体任务逻辑。它本身不执行任何任务,而是等待Timer来调度执行。
  2. Timer类

    • Timer是一个工具类,用于调度一个线程以在将来某个时间执行指定的任务。
    • 主要功能:作为定时器,负责调度和管理TimerTask任务。它可以安排任务执行一次,或者定期重复执行。

2) 协作方式

  • Timer和TimerTask通常成对出现。Timer作为定时器,负责调度和管理TimerTask任务;而TimerTask则是定时任务的具体实现,由Timer来调度执行。
  • 一个Timer可以调度任意多个TimerTask,所有任务都存储在一个队列中顺序执行。如果需要多个TimerTask并发执行,则需要创建多个Timer实例(因为每个Timer仅对应一个线程)。

3) 使用场景与特点

  1. TimerTask

    • 适用于需要在指定时间执行任务的场景。
    • 提供了简单的接口,使得任务的调度变得简单。
    • 可以根据需要设置任务的执行时间和执行周期。
  2. Timer

    • 适用于需要调度和管理多个定时任务的场景。
    • 线程安全,但不保证任务执行的精确性(因为基于单线程执行)。
    • 如果某个任务很耗时,可能会影响其他计划任务的执行。因此,在JDK 1.5及以上版本中,建议使用ScheduledThreadPoolExecutor来代替Timer执行计划任务。

4) 异常处理与线程管理

  1. 异常处理

    Timer线程不会捕获异常。如果TimerTask抛出了未检查的异常,会终止Timer线程,从而导致其他计划任务无法得到继续执行。因此,在TimerTask的run()方法中捕获所有可能的异常是非常重要的。
  2. 线程管理

    • Timer内部使用了一个线程(TimerThread)来顺序执行所有的TimerTask任务。
    • 可以通过调用Timer.cancel()方法来终止Timer线程。另外,如果创建Timer时将其设置为守护线程(使用new Timer(true)),则当且仅当进程结束时,该守护线程会自动注销。

4、ScheduledExecutorService实现定时任务

ScheduledExecutorService 是 Java 中用于调度任务的接口,它继承自 ExecutorService,提供了在给定延迟后运行任务、定期执行任务等能力

4.1)ScheduledExecutorService实现定时任务案例

// 创建一个ScheduledThreadPoolExecutor,这里使用1个线程
//        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);// 创建一个实现了Runnable接口的任务Runnable task = new Runnable() {@Overridepublic void run() {//执行定时逻辑System.out.println();}};// 安排任务在初始延迟后执行,然后每隔指定的周期重复执行(这里使用不重复执行作为示例)// 如果需要重复执行,请使用scheduleAtFixedRate或scheduleWithFixedDelay方法
//        executor.schedule(task, 0, TimeUnit.SECONDS); // 立即执行,延迟时间为0秒executor.scheduleWithFixedDelay(task, 5, 10, TimeUnit.SECONDS);// 注意:在实际应用中,您可能需要在某个时刻关闭executor,以避免资源泄露// 这通常是在应用程序关闭或不再需要定时任务时进行的// 例如,您可以在main方法的最后添加以下代码(但这将阻止程序立即退出):// executor.shutdown();// 如果希望等待所有任务完成后再关闭,可以使用:// executor.shutdownNow(); // 或者更优雅地等待任务完成:executor.awaitTermination(...);

4.2)ScheduledExecutorService的常用方法

schedule(Runnable command, long delay, TimeUnit unit): 在指定的延迟时间后执行一次任务。
schedule(Callable<V> callable, long delay, TimeUnit unit): 在指定的延迟时间后执行一次任务,并返回一个可获取结果的 Future 对象。
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit): 在初始延迟时间后开始执行任务,并以固定的时间间隔重复执行任务。
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit): 在初始延迟时间后开始执行任务,并在每次任务完成后延迟指定的时间再执行下一次任务。
submit(Callable<V> task): 提交一个可获取结果的任务,并返回一个表示任务执行结果的 Future 对象。
submit(Runnable task): 提交一个不返回结果的任务,并返回一个表示任务执行完成的 Future 对象。
shutdown(): 优雅地关闭 ScheduledExecutorService,等待已提交的任务执行完毕。
shutdownNow(): 强制关闭 ScheduledExecutorService,立即停止所有任务的执行。

注意:

虽然使用ScheduledExecutorService实现定时任务如果未捕获异常线程不会像用timer实现定时任务而终止,但是如果遇到了未捕获的异常,此定时任务会停止执行,不会开始下一次定时任务,线程会阻塞在异常处,因此即使使用ScheduledExecutorService实现定时任务也建议在run方法内捕获异常,保证即使这次遇到异常,下次任务能够定时执行。

4.3)Timer VS ScheduledExecutorService

Timer 和 ScheduledExecutorService 都是 Java 中用于执行定时任务的工具,但它们之间存在一些关键差异。以下是对这两者的详细比较:

1)线程模型

  1. Timer
    • Timer 是单线程的,每创建一个 Timer 实例,就会创建一个新的线程(TimerThread)来执行任务。
    • 如果一个 TimerTask 执行的时间过长,它会独占 Timer 对象,导致后续的任务无法及时执行,必须等待当前任务完成后才能继续。
    • Timer 默认情况下不是守护线程,但可以设置为守护线程(new Timer(true))。当进程中没有其他非守护线程时,守护线程将销毁。
  2. ScheduledExecutorService
    • ScheduledExecutorService 是基于线程池实现的,支持多个任务并发执行。
    • 线程池中的线程数量可以根据需求进行配置,因此可以同时执行多个任务,而不会相互阻塞。
    • ScheduledExecutorService 提供了更灵活和强大的线程管理功能。

2)任务调度

  1. Timer
    • Timer 对调度的支持是基于绝对时间的,因此任务对系统时钟的改变是敏感的。
    • 如果 TimerTask 抛出未检查的异常,Timer 将会产生无法预料的行为。具体来说,Timer 线程并不捕获异常,所以 TimerTask 抛出的未检查的异常会终止 Timer 线程。此时,已经被安排但尚未执行的 TimerTask 永远不会再执行了,新的任务也不能被调度。
  2. ScheduledExecutorService
    • ScheduledExecutorService 只支持相对时间进行调度。
    • 它提供了 scheduleAtFixedRate 和 scheduleWithFixedDelay 两种方法,允许更灵活地安排任务的执行。
    • 如果任务抛出异常,它不会影响其他任务的执行(除非异常导致整个线程池被关闭)。

3)任务取消与资源管理

  1. Timer
    • Timer 中的 cancel() 方法可以将任务队列中的全部任务进行取消,但有时并不一定停止任务,因为 Timer 类中的 cancel() 方法有时并没有竞争到锁。
    • 由于 Timer 是单线程的,取消任务时可能会遇到一些竞争条件,导致任务取消不完全或延迟。
  2. ScheduledExecutorService
    • 通过 ScheduledExecutorService 安排的任务可以通过 Future 对象进行取消。调用 Future 对象的 cancel 方法可以请求取消执行此任务。
    • ScheduledExecutorService 提供了更细粒度的任务管理功能,可以单独取消某个任务,而不会影响其他任务的执行。
    • 当不再需要使用 ScheduledExecutorService 时,应该及时关闭它以释放系统资源。可以使用 shutdown 或 shutdownNow 方法来关闭线程池。

4)使用建议

  • 如果需要执行简单的、少量的定时任务,并且不需要并发执行,那么 Timer 可能是一个合适的选择。
  • 如果需要执行大量的定时任务,或者需要并发执行多个任务,那么 ScheduledExecutorService 是更好的选择。它提供了更强大的线程管理功能和更灵活的任务调度能力。

5、@Scheduled注解实现定时任务

在Spring框架中,@Scheduled注解提供了一种非常方便的方式来实现定时任务。

5.1)@Scheduled注解定时任务实现案例

首先,确保你的Spring项目已经包含了必要的依赖项,比如spring-contextspring-scheduling。如果你使用的是Maven项目,可以在pom.xml中添加以下依赖(如果Spring Boot已经包含了这些依赖,则无需重复添加):

<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context</artifactId>  <version>你的Spring版本</version>  
</dependency>  
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-scheduling</artifactId>  <version>你的Spring版本</version>  
</dependency>

然后,在你的Spring配置类(通常是带有@Configuration注解的类)或Spring Boot的主类上添加@EnableScheduling注解,以启用Spring的计划任务功能:

import org.springframework.context.annotation.Configuration;  
import org.springframework.scheduling.annotation.EnableScheduling;  @Configuration  
@EnableScheduling  
public class SchedulingConfig {  // 这里可以添加其他配置  
}

 接下来,创建一个包含定时任务的类,并使用@Scheduled注解来标记定时方法。例如:

import org.springframework.scheduling.annotation.Scheduled;  
import org.springframework.stereotype.Component;  @Component  
public class ScheduledTasks {  // 每5秒执行一次  @Scheduled(fixedRate = 5000)  public void reportCurrentTime() {  System.out.println("当前时间: " + System.currentTimeMillis());  }  // 每天凌晨1点执行一次(需要cron表达式)  @Scheduled(cron = "0 0 1 * * ?")  public void executeDailyTask() {  System.out.println("执行每日任务: " + System.currentTimeMillis());  }  
}

5.2)@Scheduled注解属性介绍

cron():用于指定Cron表达式,表示任务的执行时间规则。例如0 0 * * * ?表示每天的凌晨12点执行一次任务。
zone():用于指定Cron表达式的时区,默认为空字符串。如果需要根据不同的时区执行任务,则可以设置该属性。
fixedDelay()和fixedDelayString():用于指定任务的固定延迟时间,即任务结束后等待多长时间再次执行。默认值为-1,表示不使用固定延迟。
fixedRate()和fixedRateString():用于指定任务的固定频率,即任务开始执行后多长时间再次执行。默认值为-1,表示不使用固定频率。
initialDelay()和initialDelayString():用于指定任务的初始延迟时间,即任务首次执行前等待多长时间。默认值为-1,表示立即执行。
timeUnit():用于指定时间单位,可选值有TimeUnit.MILLISECONDS(毫秒,默认值)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分钟)等

fixedDelay + initialDelay 属性功能上就等价于 Timer 的schedule方法了,

fixedRate+initialDelay属性功能上就等价于 Timer 的 scheduleAtFixedRate 方法了

6、分布式定时任务

前面所有的定时任务,无论是基于线程类,还是基于 JDK 自带的定时任务,还是基于Spring提供的Spring Task,都无法在分布式环境下使用,并且不支持持久化,一旦服务重启所有的定时任务都将发生丢失,所以我们需要使用到其它的第三方成熟的定时任务框架。

Quartz:是一个功能强大的开源作业调度框架,用于在Java应用程序中实现定时任务调度和作业调度。

XXL-Job:是一个轻量级分布式任务调度平台。特点是平台化,易部署,开发迅速、学习简单、轻量级、易扩展。由调度中心和执行器功能完成定时任务的执行。调度中心负责统一调度,执行器负责接收调度并执行。

Elastic-Job:是一个开源的分布式任务调度解决方案,它是基于Java的轻量级分布式调度框架

三者的比较

功能和特性: Quartz:Quartz是一个功能强大的作业调度框架,支持灵活的任务调度策略、分布式集群、任务持久化等特性。它具有丰富的API和扩展点,可以根据需求进行定制开发和扩展。 XXL-Job:XXL-Job是一个分布式任务调度平台,提供了可视化操作界面、多种任务调度方式、分片任务支持等特性。它注重于任务的管理和监控,并提供了报警与告警功能。 Elastic-Job:Elastic-Job是一个轻量级的分布式任务调度解决方案,支持分布式任务调度、弹性扩缩容、任务监控和管理等特性。它注重于任务的弹性扩展和容错机制。

分布式支持: Quartz:Quartz在分布式场景中需要基于数据库锁来保证操作的唯一性,通过多个节点的异步运行实现高可用性。但它没有执行层面的任务分片机制。 XXL-Job:XXL-Job提供了分布式集群的支持,可以实现任务的负载均衡和高可用性。它支持分片任务和动态调整任务节点数量的特性。 Elastic-Job:Elastic-Job支持分布式任务调度,具备弹性扩缩容能力,可以根据任务的执行情况动态调整任务节点数量。

可视化和管理界面: Quartz:Quartz本身没有提供可视化的任务管理界面,需要通过其他工具或自行开发来实现。 XXL-Job:XXL-Job提供了简洁直观的任务管理界面,方便用户进行任务的创建、编辑、状态查看等操作。 Elastic-Job:Elastic-Job提供了任务监控和管理功能,可以查看任务的执行日志、运行状态、统计信息等。

社区活跃度和生态系统: Quartz:Quartz是一个非常成熟且广泛使用的作业调度框架,拥有强大的社区支持和丰富的生态系统。 XXL-Job:XXL-Job也有一个活跃的社区,并且在国内得到广泛应用和认可。 Elastic-Job:Elastic-Job相对较新,并且社区规模较小,但其在分布式任务调度领域有一定的影响力。

Quartz在功能和扩展性上非常强大,适用于复杂的任务调度需求。XXL-Job注重于任务管理和监控,并提供了可视化的操作界面。Elastic-Job轻量级且具备分布式任务调度和弹性扩缩容能力。

总结

线程+休眠实现定时任务,是最简单实现定时任务的方式了,但这只是提供一种思路,实际开发中几乎不会使用

JDK自带的定时任务Timer和ScheduledExecutorService,我们需要了解两者的区别

Timer是单线程的,一旦发生异常,将终止所有的任务;Timer是绝对时间的,会受到系统时间的影响 ScheduledExecutorService是基于线程池,是多线程的,一旦发生异常,不会终止所有的任务;ScheduledExecutorService是相对时间 ,不会受到系统时间的影响 注意区固定间隔和固定频率的区别 Spring Task实现的定时任务是基于线程池,是多线程的,一旦发生异常,不会终止所有的任务;基于相对时间,不会受到系统时间的影响

分布式定时任务,一般是直接使用第三方成熟的定时任务框架,当然如果你公司资金充足可以选择开发定制化定时任务框架。选用开源的第三方成熟定时任务框架,好处在于功能完善、免费,代码质量也是有保障的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有趣的python库:用 difflib 实现文本差异的可视化

一&#xff0c;介绍 difflib 模块是Python标准库的一部分&#xff0c;提供了一系列用于比较序列的类和函数&#xff0c;特别适用于文本比较任务。这个模块可以帮助用户发现两个文本文件或字符串序列之间的差异&#xff0c;并以多种格式展示这些差异&#xff0c;比如这样&#…

关于Java部署项目,文件上传路径问题 、Windows是\ linux是/

Windows是\ linux是/ &#xff0c;踩坑。报错如下&#xff1a;

了解郑州自闭症寄宿学校:提供专业康复服务与关怀

在自闭症儿童的教育与康复领域&#xff0c;寄宿学校以其独特的教育模式和全面的关怀体系&#xff0c;为众多家庭提供了重要的支持。而在众多寄宿学校中&#xff0c;广州的星贝育园自闭症儿童寄宿制学校以其专业的康复服务和无微不至的关怀&#xff0c;成为了众多自闭症儿童及其…

【AGC005D】~K Perm Counting(计数抽象成图)

容斥原理。 求出f(m) &#xff0c;f(m)指代至少有m个位置不合法的方案数。 怎么求&#xff1f; 注意到位置为id&#xff0c;权值为v ,不合法的情况&#xff0c;当且仅当 v idk或 v id-k 因此&#xff0c;我们把每一个位置和权值抽象成点 &#xff0c;不合法的情况之间连一…

BEC商务英语高级相当于托福多少分?柯桥英语等级考试

虽然托福与BEC没有官方的换算标尺&#xff0c;但是我们可以用雅思作为桥梁来进行换算。 ETS发布托福和雅思分数换算表的主要目的是帮助申请人更好的对比这两种考试的成绩&#xff0c;以便于申请工作展开。官方版本的雅思与托福分数换算表如下&#xff1a; 由于BEC与雅思是同属…

STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53

STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53 1. 概述 前面的一系列文章中&#xff0c;我们介绍了整体的BootLoader的一个方案&#xff0c;现在我们针对该BootLoader设计多个命令&#xff0c;下面我们来讲述获取芯片ID的命令-0x53。 1.1 芯片Device ID和类型ID描述 STM3…

JVM和GC案例详解

接上文JVM环境配置说明&#xff1a;上文博客 一、JVM远程连接设置 1. JMX方式连接(这种方式没有GC监控)&#xff0c;设置如下 2. 连接成功后可以查看基础配置参数(和服务器配置一致) 2. jstatd方式连接(这种方式没有CPU监控) 添加jstatd方式连接 双击Tomcat&#xff0…

sklearn机器学习实战——支持向量机四种核函数分类任务全过程(附完整代码和结果图)

sklearn机器学习实战——支持向量机四种核函数分类任务全过程&#xff08;附完整代码和结果图&#xff09; 关于作者 作者&#xff1a;小白熊 作者简介&#xff1a;精通python、matlab、c#语言&#xff0c;擅长机器学习&#xff0c;深度学习&#xff0c;机器视觉&#xff0c;目…

vue 解决高德地图Uncaught Error: Invalid Object: Pixel(NaN, NaN)

有点啰嗦&#xff0c;可以直接跳到最后看解决方法。 问题排查过程 原因起始于一个新需求&#xff1a;在编辑列表信息时需要修改设备位置。 按照文档一番操作&#xff0c;发现完美需求解决了。后续测试的时候就发现浏览器报错Uncaught Error: Invalid Object: Pixel(NaN, NaN)…

【2024最新】基于springboot+vue的人职匹配推荐系统lw+ppt

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…

【课程设计/毕业设计】Java家政预约管理系统源码+开发文档

项目介绍 一直想做一款家政管理系统&#xff0c;看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套管理系统。学习过程中遇到问题可以咨询留言。 在线体验 http://jiazheng.gitapp.cn/ 源码地址 https://github.com/geeeeeeeek/java_jiazh…

Mycat引领MySQL分布式部署新纪元:性能与扩展性的双重飞跃

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言&#…

使用 Helsinki-NLP 中英文翻译本地部署 - python 实现

通过 Helsinki-NLP 本地部署中英文翻译功能。该开源模型性价比相对高&#xff0c;资源占用少&#xff0c;对于翻译要求不高的应用场景可以使用&#xff0c;比如单词&#xff0c;简单句式的中英文翻译。 该示例使用的模型下载地址&#xff1a;【免费】Helsinki-NLP中英文翻译本…

Java程序打包成jar包

步骤1 打开项目结构 步骤2 配置工件 选择你要打包的模块选择主类(程序的主入口main类)提取到目标会把库文件的jar包打包到目标,一般选择这个,更方便在不同电脑上运行 步骤3 构建并生成jar包 最后,在对应的out/artifacts文件夹中找到jar包,在终端输入java -jar xxxx.jar就可以正…

Sentinel 1.80(CVE-2021-44139)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性 Report a Sentinel Security Vulnerability …

“重阳敬老情,爱心暖夕阳”__郑光荣敬老慰问

“重阳敬老情&#xff0c;爱心暖夕阳”__郑光荣敬老慰问 2024年的重阳节&#xff0c;北京正明圣达叫卖团和窦志联的志愿者们来到润龄养老院和老人一起共庆 重阳节、共同带来、 歌、 舞、 演讲、 尤其是&#xff08;北京正明圣达叫卖团&#xff09;非遗项目传承人 郑光荣带来…

爬虫prc技术----小红书爬取解决xs

知识星球&#xff1a;知识星球 | 深度连接铁杆粉丝&#xff0c;运营高品质社群&#xff0c;知识变现的工具知识星球是创作者连接铁杆粉丝&#xff0c;实现知识变现的工具。任何从事创作或艺术的人&#xff0c;例如艺术家、工匠、教师、学术研究、科普等&#xff0c;只要能获得一…

【JVM】如何判断对象是否可以被回收

引用计数法&#xff1a; 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 优点&#xff1a;实现简单&#xff0c;判…

5G NR BWP 简介

文章目录 BWP介绍BWP 分类BWP相关总结 BWP介绍 5G NR 系统带宽比4G LTE 大了很多&#xff0c;4G LTE 最大支持带宽为20MHz&#xff0c; 而5G NR 的FR1 最大支持带宽为100MH在&#xff0c; FR2 最大支持带宽为 400MH在。带宽越大&#xff0c;意味了终端功耗越多。为了减少终端的…

Nginx的正向与反向代理

一、Nginx简介 1. 什么是Nginx Nginx&#xff08;发音为“engine-x”&#xff09;是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP代理服务器。Nginx是由俄罗斯的Igor Sysoev&#xff08;伊戈尔赛索耶夫&#xff09;为解决C10k问题&#xff08;即…