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

网站建设公司怎么宣传受欢迎的大连网站建设

网站建设公司怎么宣传,受欢迎的大连网站建设,手机和网站页面模板,制作网站品牌公司文章目录 【README】【1】Quartz任务调度框架【1.1】Job调度任务【1.2】任务调度触发器Trigger【1.3】\*Quartz框架执行调度任务代码实践【1.3.1】硬编码执行Quartz调度任务【1.3.2】基于生产者模式执行quartz调度任务#xff08;推荐#xff09; 【2】spring集成Quartz【2.1… 文章目录 【README】【1】Quartz任务调度框架【1.1】Job调度任务【1.2】任务调度触发器Trigger【1.3】\*Quartz框架执行调度任务代码实践【1.3.1】硬编码执行Quartz调度任务【1.3.2】基于生产者模式执行quartz调度任务推荐 【2】spring集成Quartz【2.1】spring管理quartz组件对象【2.1.1】spring管理quartz的Job【2.1.2】spring管理quartz的JobDetail【2.1.3】spring管理quartz的Trigger【2.1.4】spirng管理quartz的Scheduler 【2.2】spring启动quartz调度器执行调度任务 【3】JDK Timer定时器【3.1】JDK Timer基础知识回顾【3.2】定时器任务单次执行【3.2.1】给定延迟时间之后执行单次任务【3.2.2】在给定时间点执行单次任务 【3.3】 定时器任务重复执行【3.3.1】在给定延迟时间后重复执行【3.2.2】在给定时间点重复执行【3.3.3】定时器任务重复执行注意点 【3.4】取消调度器与调度任务【3.4.1】 在run方法里取消调度任务 【3.5】定时器Timer与调度线程池对比【3.5.1】调度线程池执行调度任务回顾【3.5.2】定时器与调度线程池ScheduledExecutorService对比 【README】 本文部分内容总结自《spring揭秘》作者王福强非常棒的一本书墙裂推荐 本文部分内容总结自 https://juejin.cn/post/7158071449314394119 本文代码参见 github-springDiscover-chapter31 【1】Quartz任务调度框架 1Quartz是一款开源的任务调度框架 官网介绍参见 quartz-scheduler 官网介绍总结翻译 quartz是一款功能丰富的开源作业调度库可以集成几乎任何java应用从最小的单体应用到最大的电子商务系统。 quartz能够用于创建简单或复杂的调度以执行数十数百数万个作业这些作业的任务可以被定义为标准的java组件可以执行你编程让它们做的任何操作。quartz调度器包含许多企业级功能如支持JTA事务与集群。应用场景 定时执行业务逻辑如数据同步发送短信每隔一段时间执行业务逻辑如每隔5秒发送1次心跳 2相对于JDK的Timer之类的简单任务调度程序来说Quartz拥有丰富的功能如下 允许批处理任务状态的持久化批处理任务的远程调度基于web的监控接口集群支持 同一时刻只有一个任务执行当一个任务宕机之后其它服务会接管这个任务插件式的可扩展性 3Quartz组件清单 Job 抽象调度任务作业JobDetail封装job的详细信息如job名称组名称job的classJobDataMap等Trigger触发器抽象job触发规则如执行开始时间结束时间执行频率Scheduler调度器 使用Trigger定义的规则执行jobJobBuilderJob生成器用于创建Job实例TriggerBuilderTrigger生成器用于创建Trigger实例JobExecutionContextJob运行时上下文JobDataMap 封装参数键值对用于Job与JobDetail的数据交互 4Quartz基本组件关系如下 5使用 quartz任务调度框架需要引入对应maven依赖如下 dependencygroupIdorg.quartz-scheduler/groupIdartifactIdquartz/artifactIdversion2.3.2/version /dependency【1.1】Job调度任务 1quartz中调度任务job定义 public interface Job {void execute(JobExecutionContext var1) throws JobExecutionException; }2调度任务实现job接口 public class TomScheduleJob implements Job {Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {// do sth.System.out.println(MyScheduleJob#当前时间 BusiDatetimeUtils.getNowText());} }【1.2】任务调度触发器Trigger 1触发器定义job触发规则如每隔10分钟执行1次每天早上7点9点准时执行1次 2触发器Trigger定义如下 public interface Trigger extends Serializable, Cloneable, ComparableTrigger {long serialVersionUID -3904243490805975570L;int MISFIRE_INSTRUCTION_SMART_POLICY 0;int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY -1;int DEFAULT_PRIORITY 5;TriggerKey getKey();JobKey getJobKey();String getDescription();String getCalendarName();JobDataMap getJobDataMap();int getPriority();boolean mayFireAgain();Date getStartTime();Date getEndTime();Date getNextFireTime();Date getPreviousFireTime();Date getFireTimeAfter(Date var1);Date getFinalFireTime();int getMisfireInstruction();TriggerBuilder? extends Trigger getTriggerBuilder();ScheduleBuilder? extends Trigger getScheduleBuilder();boolean equals(Object var1);int compareTo(Trigger var1); // ... }2触发器的两种主要实现 SimpleTrigger指定基于时间间隔的调度规则触发规则CronTrigger指定基于cron表达式的调度规则包括但不限于时间间隔还可以指定具体时间执行触发规则更加灵活 【1.3】*Quartz框架执行调度任务代码实践 【1.3.1】硬编码执行Quartz调度任务 【TomQuartzJob】 public class TomQuartzJob implements Job {Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {// do sth.System.out.println(TomQuartzJob#当前时间 BusiDatetimeUtils.getNowText());} }【TomQuartzJobMain】 public class TomQuartzJobMain {public static void main(String[] args) throws Exception {executeScheduleJob();}private static void executeScheduleJob() throws ParseException, SchedulerException {// 新建触发器SimpleTriggerImpl simpleTrigger new SimpleTriggerImpl(tomSimpleTrigger, tomSimpleTriggerGroup, new Date(), null, SimpleTriggerImpl.REPEAT_INDEFINITELY, 5000); // 每隔5秒执行1次CronTriggerImpl cronTrigger new CronTriggerImpl(tomSimpleTrigger, tomSimpleTriggerGroup, */5 * * * * ?);// 新建调度器Scheduler scheduler new StdSchedulerFactory().getScheduler();scheduler.start();// 新建调度任务详情JobDetailImpl tomJobDetail new JobDetailImpl(tomJobDetail, TomQuartzJob.class);// 新增调度任务这里是新增并没有执行执行由触发器来负责 // scheduler.scheduleJob(tomJobDetail, simpleTrigger);scheduler.scheduleJob(tomJobDetail, cronTrigger);} }【1.3.2】基于生产者模式执行quartz调度任务推荐 1基于生成器模式执行调度任务 参考 quick-start 【TomTimeRemindJob】 public class TomTimeRemindJob implements Job {Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println();context.getMergedJobDataMap().forEach((k,v)- System.out.println(k v));context.getJobDetail().getJobDataMap().forEach((k,v)- System.out.println(k v));System.out.println(TomTimeRemindJob now BusiDatetimeUtils.getNowText());} }【TomTimeRemindJobMain】 public class TomTimeRemindJobMain {public static void main(String[] args) throws SchedulerException {// 创建调度器实例Scheduler scheduler StdSchedulerFactory.getDefaultScheduler();// 开启调度器scheduler.start();// 执行调度作业executeScheduleJob(scheduler);// 关闭调度器 // scheduler.shutdown();}private static void executeScheduleJob(Scheduler scheduler) throws SchedulerException {// 创建JobDetail并与TomTimeRemindJob 绑定JobDetail jobDetail JobBuilder.newJob(TomTimeRemindJob.class).withIdentity(tomJob01, tomJob01Group).build();// 立即触发作业执行每5秒重复一次Trigger simpleTrigger TriggerBuilder.newTrigger().withIdentity(tomTrigger01, tomTrigger01Group).startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();// 告诉quartz使用我们的触发器调度作业scheduler.scheduleJob(jobDetail, simpleTrigger);} }【2】spring集成Quartz 1通过上述代码【TomTimeRemindJobMain】 本文发现使用Quartz框架执行调度任务需要依赖以下4个组件Job JobDetail Trigger Scheduler Job调度任务 JobDetail 用于封装job详细信息 Trigger触发器定义触发规则 Scheduler调度器根据触发器的规则执行调度任务作业 2可以想到spring集成Quartz的底层原理 把JobJobDetail SimpleTrigger Scheduler对象创建与依赖关系装配由spring来完成无需客户端实现 spring采用工厂方法FactoryBean来管理quartz调度任务所需组件 3spring集成Quartz需要新增maven依赖如下 dependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion6.1.10/version/dependency【2.1】spring管理quartz组件对象 1本章节部分内容总结自 spring-quartz-schedule 【2.1.1】spring管理quartz的Job 1spring提供了QuartzJobBean用于抽象调度任务自定义调度任务需要继承QuartzJobBean并重写executeInternal()方法 2QuartzJobBean定义注意quartz的JobDetail封装了Job的class对象由JobDetail实例化job所以spring无需注册job public abstract class QuartzJobBean implements Job {public QuartzJobBean() {}public final void execute(JobExecutionContext context) throws JobExecutionException {try {BeanWrapper bw PropertyAccessorFactory.forBeanPropertyAccess(this);MutablePropertyValues pvs new MutablePropertyValues();pvs.addPropertyValues(context.getScheduler().getContext());pvs.addPropertyValues(context.getMergedJobDataMap());bw.setPropertyValues(pvs, true);} catch (SchedulerException var4) {throw new JobExecutionException(var4);}this.executeInternal(context);}protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException; }【自定义job继承QuartzJobBean】TomSpringQuartzJobBean public class TomSpringQuartzJobBean extends QuartzJobBean {Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {System.out.println(TomSpringQuartzJobBean #当前时间 BusiDatetimeUtils.getNowText());} }【2.1.2】spring管理quartz的JobDetail 1在quartz中 job抽象了调度任务而job的上下文信息由JobDetail封装Job与JobDetail的数据交互通过JobDataMap实现 2spring注册JobDetail有两种方式 方式1 JobDetailFactoryBean 注册JobDetail 推荐 方式2 通过 MethodInvokingJobDetailFactoryBean 注册JobDetail 本文不介绍 【springquartz.xml】 JobDetailFactoryBean 注册JobDetail ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 通过 JobDetailFactoryBean 注册JobDetail --bean classorg.springframework.scheduling.quartz.JobDetailFactoryBeanproperty namename valuetomJob /property namegroup valuetomJobGroup /property namejobClass valuecom.tom.springnote.chapter31schedule.springquartz.SpringScheduleJob /property namedurability valuetrue /property namedescription valuetomJobDetail /property namejobDataMapmapentry keymessage valuehello world /entry keycity valuechengdu //map/property/bean /beans【2.1.3】spring管理quartz的Trigger 1trigger触发器定义了执行调度任务的规则 如每5秒执行1次 2spring也是通过FactoryBean注册Trigger SimpleTriggerFactoryBean 简单触发器CronTriggerFactoryBean 带有cron表达式的触发器 【springquartz.xml】 SimpleTriggerFactoryBean 注册Trigger ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 通过 JobDetailFactoryBean 注册JobDetail --bean idtomJobDetail classorg.springframework.scheduling.quartz.JobDetailFactoryBeanproperty namename valuetomJob /property namegroup valuetomJobGroup /property namejobClass valuecom.tom.springnote.chapter31schedule.springquartz.SpringScheduleJob /property namedurability valuetrue /property namedescription valuetomJobDetail /property namejobDataMapmapentry keymessage valuehello world /entry keycity valuechengdu //map/property/bean!-- 通过 SimpleTriggerFactoryBean 注册触发器 --bean classorg.springframework.scheduling.quartz.SimpleTriggerFactoryBeanproperty namename valuetomTrigger /property namegroup valuetomTriggerGroup /property namejobDetail reftomJobDetail /property namerepeatInterval value5000 / !-- 单位毫秒每5秒执行1次--property namerepeatCount value-1 / !-- -1表示永远重复 --/bean!-- 通过 CronTriggerFactoryBean 注册触发器 --bean classorg.springframework.scheduling.quartz.CronTriggerFactoryBeanproperty namename valuetomCronTrigger /property namegroup valuetomCronTriggerGroup /property namejobDetail reftomJobDetail /property namecronExpression ref*/3 * * * * ? / !-- 每3秒执行1次--/bean/beans3补充 多个trigger定义的规则可以同时作用于同一个JobDetail 或Job 本文认为多个Trigger规则的组合太过复杂1个trigger对应1个Job足够满足日常业务需求本文不再深入研究多个trigger组合的情况有兴趣的同学自行研究 【2.1.4】spirng管理quartz的Scheduler 1scheduler调度器使用触发器Trigger定义的规则执行调度任务job 2spring通过SchedulerFactoryBean注册scheduler 【springquartz.xml】 SchedulerFactoryBean注册scheduler ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 通过 JobDetailFactoryBean 注册JobDetail --bean idtomJobDetail classorg.springframework.scheduling.quartz.JobDetailFactoryBeanproperty namename valuetomJob /property namegroup valuetomJobGroup /property namejobClass valuecom.tom.springnote.chapter31schedule.springquartz.TomSpringQuartzJobBean /property namedurability valuetrue /property namedescription valuetomJobDetail /property namejobDataMapmapentry keymessage valuehello world /entry keycity valuechengdu //map/property/bean!-- 通过 SimpleTriggerFactoryBean 注册触发器 --bean idtomSimpleTrigger classorg.springframework.scheduling.quartz.SimpleTriggerFactoryBeanproperty namename valuetomTrigger /property namegroup valuetomTriggerGroup /property namejobDetail reftomJobDetail /property namerepeatInterval value5000 / !-- 单位毫秒每5秒执行1次--property namerepeatCount value-1 / !-- -1表示永远重复 --/bean!-- 通过 CronTriggerFactoryBean 注册触发器 --bean idtomCronTrigger classorg.springframework.scheduling.quartz.CronTriggerFactoryBeanproperty namename valuetomCronTrigger /property namegroup valuetomCronTriggerGroup /property namejobDetail reftomJobDetail /property namecronExpression ref*/3 * * * * ? / !-- 每3秒执行1次--/bean!-- 通过SchedulerFactoryBean注册scheduler --bean classorg.springframework.scheduling.quartz.SchedulerFactoryBeanproperty nametriggers !-- 可以装配多个触发器当然日常开发1个足够 --listref beantomSimpleTrigger /ref beantomCronTrigger //list/property/bean /beans【2.2】spring启动quartz调度器执行调度任务 1spring容器ApplicationContext启动时SchedulerFactoryBean所管理的调度器Scheduler跟着自动启动且Scheduler随着ApplicationContext的关闭而自动关闭 当调度任务的所有对象实例注册到ioc容器后ApplicationContext启动时Scheduler也启动Scheduler立即开始执行调度任务 【TomSpringQuartzJobBeanMain】 public class TomSpringQuartzJobBeanMain {public static void main(String[] args) {ClassPathXmlApplicationContext springContext new ClassPathXmlApplicationContext(chapter31schedule/springquartz.xml);((AbstractApplicationContext) springContext).registerShutdownHook();} }【执行效果】 2个调度任务在执行因为有2个触发器tomSimpleTrigger-每5秒执行1次tomCronTrigger-每3秒执行1次 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:23.623 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:24.002 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:27.000 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:28.505 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:30.000 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:33.010 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:33.501 TomSpringQuartzJobBean #当前时间2024-10-13 21:42:36.003【3】JDK Timer定时器 【3.1】JDK Timer基础知识回顾 1Timer定时器组件 TimerTask抽象调度任务Timer抽象调度器用于定义任务触发规则并执行调度任务 类似于肩负了quartz的Scheduler与Trigger职责 只能配置简单规则不能配置cron表达式 2Timer使用TimerTask抽象调度任务自定义调度任务需要继承TimerTask 由代码可知 TimerTask本质上是Runnable即可以提交给线程的任务 public abstract class TimerTask implements Runnable {// ... }3部分代码总结自 java-timer-and-timertask 【3.2】定时器任务单次执行 【3.2.1】给定延迟时间之后执行单次任务 1在当前时间等待给定延迟时间之后执行调度任务 【OnceTimerTaskExecuteAfterDelayMain】给定延迟时间之后仅执行1次调度任务 public class OnceTimerTaskExecuteAfterDelayMain {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定延迟时间(5s)之后执行调度任务仅执行1次timer.schedule(timerTask, 5000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} } public void schedule(TimerTask task, long delay) { if (delay 0)throw new IllegalArgumentException(Negative delay.);sched(task, System.currentTimeMillis()delay, 0); // period0 表示当前任务仅执行1次 } private void sched(TimerTask task, long time, long period) { // ... }【解说】period参数表示2个相邻任务执行的时间间隔单位毫秒 若为0表示仅执行1次 若为整数表示时间间隔 【执行效果】 当前时间2024-10-16 20:51:52.281 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 20:51:57.298 主线程结束 当前时间2024-10-16 20:51:57.298【3.2.2】在给定时间点执行单次任务 1在给定时间点执行调度任务 【OnceTimerTaskExecuteAtGivenTime】 在给定时间点执行调度任务仅执行1次 public class OnceTimerTaskExecuteAtGivenTime {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定时间点当前时间加5秒的时间执行调度任务仅执行1次timer.schedule(timerTask, BusiDatetimeUtils.timeAfterSecond(5));System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} } public void schedule(TimerTask task, Date time) {sched(task, time.getTime(), 0); // period0 表示仅执行1次 }【执行效果】 当前时间2024-10-16 20:55:09.981 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 20:55:14.984 主线程结束 当前时间2024-10-16 20:55:14.986【3.3】 定时器任务重复执行 【3.3.1】在给定延迟时间后重复执行 1使用Timer定时器在给定延迟时间后重复执行调度任务 【RepeatableTimerTaskExecuteAfterDelayMain】 public class RepeatableTimerTaskExecuteAfterDelayMain {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定延迟时间(5s)之后执行调度任务间隔2秒重复执行timer.schedule(timerTask, 5000, 2000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(10); // 睡眠10s后关闭定时器以便调度任务可以重复执行} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} }【执行效果】 当前时间2024-10-16 21:01:49.933 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 21:01:54.950 线程id15 当前时间2024-10-16 21:01:56.951 线程id15 当前时间2024-10-16 21:01:58.957 主线程结束 当前时间2024-10-16 21:01:59.946【3.2.2】在给定时间点重复执行 【RepeatableTimerTaskExecuteAtGivenTime】 public class RepeatableTimerTaskExecuteAtGivenTime {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定时间点当前时间加5秒的时间执行调度任务间隔2s重复执行timer.schedule(timerTask, BusiDatetimeUtils.timeAfterSecond(5), 2000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} }【执行效果】 当前时间2024-10-16 21:07:12.258 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 21:07:17.260 线程id15 当前时间2024-10-16 21:07:19.261 线程id15 当前时间2024-10-16 21:07:21.275 主线程结束 当前时间2024-10-16 21:07:22.261【3.3.3】定时器任务重复执行注意点 1 若一个任务执行耗时大于调度间隔或周期period则会延迟整个执行链无论是在延迟时间后还是给定时间点执行 【RepeatableTimerTaskDelayWholeChainAtGivenTime】 public class RepeatableTimerTaskDelayWholeChainAtGivenTime {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());try {TimeUnit.SECONDS.sleep(5); // 模拟单个任务执行耗时5秒} catch (InterruptedException e) {throw new RuntimeException(e);}}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定时间点当前时间加5秒的时间执行调度任务间隔2s重复执行timer.schedule(timerTask, BusiDatetimeUtils.timeAfterSecond(1), 2000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(30); // 延迟30秒等待执行重复调度任务} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel(); System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} }【执行效果】 程序中设置定时器每隔2s执行调度任务而运行效果是每隔5s执行调度任务 原因是任务执行睡眠5s模拟了业务逻辑耗时当上一个任务执行完成后下一个任务才会执行即单个任务执行耗时过长会延迟整体任务调度 当前时间2024-10-16 21:36:40.218 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 21:36:41.222 线程id15 当前时间2024-10-16 21:36:46.236 线程id15 当前时间2024-10-16 21:36:51.247 线程id15 当前时间2024-10-16 21:36:56.258 线程id15 当前时间2024-10-16 21:37:01.272 线程id15 当前时间2024-10-16 21:37:06.285 主线程结束 当前时间2024-10-16 21:37:10.224【3.4】取消调度器与调度任务 1取消调度器执行的方法 调用 Timer.cancel()方法取消调度器 若调度器有任务运行则不结束 若调度器没有任务运行则可以结束 2取消调度任务的方法 方法1 在TimerTask内部run方法执行cancel()方法取消当前调度任务执行方法2 在TimerTask内部run()方法中强行终止当前线程执行 【3.4.1】 在run方法里取消调度任务 【CancelRepeatableTimerTaskInsideRun】 public class CancelRepeatableTimerTaskInsideRun {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());cancel(); // 取消当前调度任务 本来是重复调度结果仅执行1次}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定时间点当前时间加5秒的时间执行调度任务间隔2s重复执行timer.schedule(timerTask, BusiDatetimeUtils.timeAfterSecond(5), 2000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} }【执行效果】 当前时间2024-10-16 21:48:59.496 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 21:49:04.501 主线程结束 当前时间2024-10-16 21:49:09.510【3.5】定时器Timer与调度线程池对比 【3.5.1】调度线程池执行调度任务回顾 【RepeatableTaskExecuteBySchedulerThreadPoolMain】使用调度线程池执行重复任务 public class RepeatableTaskExecuteBySchedulerThreadPoolMain {public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(1); // 不要这样用本文仅演示Runnable task new Runnable() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());}};// 重复任务间隔2s执行1次scheduledExecutorService.scheduleAtFixedRate(task, 0, 2000, TimeUnit.MILLISECONDS);} }【执行效果】 线程id15 当前时间2024-10-16 22:03:46.625 线程id15 当前时间2024-10-16 22:03:48.580 线程id15 当前时间2024-10-16 22:03:50.579 线程id15 当前时间2024-10-16 22:03:52.578【注意】 实际开发过程中不要使用 Executors.newScheduledThreadPool(1) 如下面代码所示该方法初始化的最大线程个数无限大这是有问题的 线程个数无限大会导致cpu时间片被耗尽切换不到或无法及时切换到正常业务逻辑的线程上导致系统假死 public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE,DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,new DelayedWorkQueue());}【3.5.2】定时器与调度线程池ScheduledExecutorService对比 1定时器Timer与调度线程池ScheduledExecutorService对比 定时器Timer对系统时钟变化非常敏感而调度线程池不会定时器Timer只有1个执行线程 而调度线程池可以配置多个TimerTask内部run方法执行抛出运行时异常则当前线程被杀死导致后续任务不执行而调度线程池中的线程抛出异常仅运行中的任务被取消但线程还存在即其他任务还是可以被执行 2模拟TimerTask的run方法内部抛出异常 public class RepeatableTimerTaskExecuteThrowException {public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(线程id%s 当前时间%s \n, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());throw new RuntimeException(mock runtime exception);}};// 通过jdk 定时器执行调度任务Timer timer new Timer();System.out.println(当前时间 BusiDatetimeUtils.getNowText());// 在给定时间点当前时间加5秒的时间执行调度任务间隔2s重复执行timer.schedule(timerTask, BusiDatetimeUtils.timeAfterSecond(5), 2000);System.out.println(after timer.schedule()新增调度任务之后);try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}// 取消调度器执行(主线程结束)timer.cancel();System.out.println(主线程结束 当前时间 BusiDatetimeUtils.getNowText());} }【执行效果】 显然若TimerTask内部run方法抛出运行时异常则整个定时器执行完成定时器线程被杀死 当前时间2024-10-16 22:12:37.801 after timer.schedule()新增调度任务之后 线程id15 当前时间2024-10-16 22:12:42.803 Exception in thread Timer-0 java.lang.RuntimeException: mock runtime exceptionat com.tom.springnote.chapter31schedule.origintimer.RepeatableTimerTaskExecuteThrowException$1.run(RepeatableTimerTaskExecuteThrowException.java:22)at java.base/java.util.TimerThread.mainLoop(Timer.java:566)at java.base/java.util.TimerThread.run(Timer.java:516) 主线程结束 当前时间2024-10-16 22:12:47.806 3模拟调度线程池ScheduledExecutorService的run方法内部抛出异常 【RepeatableTaskExecuteBySchedulerThreadPoolThrowExceptionMain】 public class RepeatableTaskExecuteBySchedulerThreadPoolThrowExceptionMain {static class BusiTask implements Runnable {private String flag;public BusiTask(String flag) {this.flag flag;}Overridepublic void run() {System.out.printf(flag%s, 线程id%s 当前时间%s \n, flag, Thread.currentThread().getId(), BusiDatetimeUtils.getNowText());if (Objects.equals(exception, flag)) {throw new RuntimeException(mock runtime exception);}}}public static void main(String[] args) {ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(2);// 重复任务间隔2s执行1次scheduledExecutorService.scheduleAtFixedRate(new BusiTask(exception), 0, 2000, TimeUnit.MILLISECONDS);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}// 第2次添加任务scheduledExecutorService.scheduleAtFixedRate(new BusiTask(zhangsan), 0, 2000, TimeUnit.MILLISECONDS);} }【执行效果】 显然即便抛出异常 我们还是可以向调度线程池添加调度任务 flagexception, 线程id15 当前时间2024-10-16 22:25:34.802 flagzhangsan, 线程id15 当前时间2024-10-16 22:25:36.750 flagzhangsan, 线程id15 当前时间2024-10-16 22:25:38.756 flagzhangsan, 线程id15 当前时间2024-10-16 22:25:40.764
文章转载自:
http://www.morning.kzdgz.cn.gov.cn.kzdgz.cn
http://www.morning.jrpmf.cn.gov.cn.jrpmf.cn
http://www.morning.mpyry.cn.gov.cn.mpyry.cn
http://www.morning.xsklp.cn.gov.cn.xsklp.cn
http://www.morning.clwhf.cn.gov.cn.clwhf.cn
http://www.morning.mzbyl.cn.gov.cn.mzbyl.cn
http://www.morning.pqndg.cn.gov.cn.pqndg.cn
http://www.morning.ypqwm.cn.gov.cn.ypqwm.cn
http://www.morning.dycbp.cn.gov.cn.dycbp.cn
http://www.morning.gswfs.cn.gov.cn.gswfs.cn
http://www.morning.tgyqq.cn.gov.cn.tgyqq.cn
http://www.morning.ttxnj.cn.gov.cn.ttxnj.cn
http://www.morning.gmgyt.cn.gov.cn.gmgyt.cn
http://www.morning.qlrtd.cn.gov.cn.qlrtd.cn
http://www.morning.zkpwk.cn.gov.cn.zkpwk.cn
http://www.morning.kmlmf.cn.gov.cn.kmlmf.cn
http://www.morning.cklld.cn.gov.cn.cklld.cn
http://www.morning.mbmtn.cn.gov.cn.mbmtn.cn
http://www.morning.tplht.cn.gov.cn.tplht.cn
http://www.morning.nlqgb.cn.gov.cn.nlqgb.cn
http://www.morning.burpgr.cn.gov.cn.burpgr.cn
http://www.morning.lclpj.cn.gov.cn.lclpj.cn
http://www.morning.dwyyf.cn.gov.cn.dwyyf.cn
http://www.morning.hhxkl.cn.gov.cn.hhxkl.cn
http://www.morning.lcjw.cn.gov.cn.lcjw.cn
http://www.morning.tqsnd.cn.gov.cn.tqsnd.cn
http://www.morning.pbygt.cn.gov.cn.pbygt.cn
http://www.morning.qyjqj.cn.gov.cn.qyjqj.cn
http://www.morning.hjlsll.com.gov.cn.hjlsll.com
http://www.morning.caswellintl.com.gov.cn.caswellintl.com
http://www.morning.lsxabc.com.gov.cn.lsxabc.com
http://www.morning.jnrry.cn.gov.cn.jnrry.cn
http://www.morning.kqpxb.cn.gov.cn.kqpxb.cn
http://www.morning.dmzqd.cn.gov.cn.dmzqd.cn
http://www.morning.rqxmz.cn.gov.cn.rqxmz.cn
http://www.morning.ztcxx.com.gov.cn.ztcxx.com
http://www.morning.bmtyn.cn.gov.cn.bmtyn.cn
http://www.morning.wbqk.cn.gov.cn.wbqk.cn
http://www.morning.klyyd.cn.gov.cn.klyyd.cn
http://www.morning.skpdg.cn.gov.cn.skpdg.cn
http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn
http://www.morning.czrcf.cn.gov.cn.czrcf.cn
http://www.morning.cmzcp.cn.gov.cn.cmzcp.cn
http://www.morning.gcqkb.cn.gov.cn.gcqkb.cn
http://www.morning.npbkx.cn.gov.cn.npbkx.cn
http://www.morning.wnbqy.cn.gov.cn.wnbqy.cn
http://www.morning.8yitong.com.gov.cn.8yitong.com
http://www.morning.yqqgp.cn.gov.cn.yqqgp.cn
http://www.morning.pxsn.cn.gov.cn.pxsn.cn
http://www.morning.xbmwh.cn.gov.cn.xbmwh.cn
http://www.morning.kmcfw.cn.gov.cn.kmcfw.cn
http://www.morning.dpdns.cn.gov.cn.dpdns.cn
http://www.morning.mrbzq.cn.gov.cn.mrbzq.cn
http://www.morning.sryyt.cn.gov.cn.sryyt.cn
http://www.morning.ckctj.cn.gov.cn.ckctj.cn
http://www.morning.xxwfq.cn.gov.cn.xxwfq.cn
http://www.morning.xpqdf.cn.gov.cn.xpqdf.cn
http://www.morning.wtnyg.cn.gov.cn.wtnyg.cn
http://www.morning.rgtp.cn.gov.cn.rgtp.cn
http://www.morning.ckfyp.cn.gov.cn.ckfyp.cn
http://www.morning.yksf.cn.gov.cn.yksf.cn
http://www.morning.zzjpy.cn.gov.cn.zzjpy.cn
http://www.morning.mtbth.cn.gov.cn.mtbth.cn
http://www.morning.rqgbd.cn.gov.cn.rqgbd.cn
http://www.morning.bby45.cn.gov.cn.bby45.cn
http://www.morning.nqlnd.cn.gov.cn.nqlnd.cn
http://www.morning.cttti.com.gov.cn.cttti.com
http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn
http://www.morning.lgwpm.cn.gov.cn.lgwpm.cn
http://www.morning.xq3nk42mvv.cn.gov.cn.xq3nk42mvv.cn
http://www.morning.yqfdl.cn.gov.cn.yqfdl.cn
http://www.morning.tturfsoc.com.gov.cn.tturfsoc.com
http://www.morning.nkjpl.cn.gov.cn.nkjpl.cn
http://www.morning.ypklb.cn.gov.cn.ypklb.cn
http://www.morning.zdxinxi.com.gov.cn.zdxinxi.com
http://www.morning.ssjtr.cn.gov.cn.ssjtr.cn
http://www.morning.pfgln.cn.gov.cn.pfgln.cn
http://www.morning.nshhf.cn.gov.cn.nshhf.cn
http://www.morning.lfqnk.cn.gov.cn.lfqnk.cn
http://www.morning.mdpkf.cn.gov.cn.mdpkf.cn
http://www.tj-hxxt.cn/news/241195.html

相关文章:

  • 公司网站未备案如何做网络销售平台
  • word可以做网站链接吗阿里云 装wordpress
  • 福建省建设人才与科技发展中心网站首页建设团队网站
  • 做网站发房源综合语录wordpress怎么添加企业网站
  • 个人网站备案描述域名和网站
  • 经营网站 备案查询seo服务内容
  • 网站设置桌面快捷方式wordpress去除acf
  • 个人网站开发如何赚钱网站规划建设心得与体会
  • 用struts2框架做的网站销售网站免费做
  • html5响应式网站模版怎么搭建一个完整的网站
  • 专业做物业网站的公司吗高端网站设计公司排名
  • 做网站用什么框架好全网整合营销
  • 扬州电商网站建设低价网站建设哪个好
  • 网站内页要不要加上关键词和描述两栏式设计网站
  • 公众号做淘宝客接入手机网站查商标名有没有被注册
  • 网站优化哪家好河南省建筑信息平台
  • 搭建网站流程网络架构有哪几层
  • 昆山市建设局网站免费营销型网站建设
  • python做爬虫和做网站成都科技网站建设费用
  • php网站制作费用学编程有什么好处
  • 网站的支付接口对接怎么做织梦个人网站模版
  • 自建网站和租用空间网站长沙企业网站排名
  • 大型网站开发技术六安网站排名优化电话
  • 怎么做记步数的程序到网站公司网站企业文化怎么做
  • 邵东做网站的公司建站需要会哪些语言
  • 国外网站推广如何做威海做网站
  • 广东省建设注册中心网站重庆安全员c证查询官网
  • 高端集团响应式企业网站模板电子商务网站建设有哪些知识点
  • 国外调色网站专业建设网站
  • 德州哪家网站建设好网站建设ui设计公司