小记:Quartz 当 Job 执行时间超过触发间隔时间时所发生的情况

一个普通的 Job 实现如下:

public class Job1 : IJob
{
    public void Execute(IJobExecutionContext context)
    {
        Console.WriteLine(DateTime.Now + ": Job1" + m);
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var props = new NameValueCollection();
        //使用简单线程池
        props["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
        //最大线程数
        props["quartz.threadPool.threadCount"] = "10";
        //线程优先级:正常
        props["quartz.threadPool.threadPriority"] = "Normal";
        //初始化调度器
        IScheduler scheduler = new StdSchedulerFactory(props).GetScheduler();

        //Cron 触发器,每隔 1 秒触发一次
        ITrigger trig = TriggerBuilder.Create().WithCronSchedule("0/1 * * * * ?").Build();
        //将作业 Job1 加入调度计划中
        scheduler.ScheduleJob(JobBuilder.Create<Job1>().Build(), trig);
        //开始执行
        scheduler.Start();

        Console.ReadLine();
        scheduler.Shutdown();
    }
}

执行结果如下:可以看到,Job1 准确的每隔 1 秒执行一次

现在问题来了:如果 Job1 中的操作执行时间很长,超过了间隔时间 1 秒,会发生什么情况?代码如下:

public class Job1 : IJob
{
    public void Execute(IJobExecutionContext context)
    {
        Console.WriteLine(DateTime.Now + ": Job1" + m);
        //等待 5 秒
        Thread.Sleep(5000);
    }
}

执行结果如下:

我们会发现,Quartz 仍然会按照我们设定的每隔 1 秒触发一次。

这是因为默认情况下,当Job执行时间超过间隔时间时,调度框架为了能让任务按照我们预定的时间间隔执行,会马上启用新的线程执行任务

若我们希望当前任务执行完之后再执行下一轮任务,也就是不要并发执行任务,该如何解决呢?

第一种方法:设置 quartz.threadPool.threadCount 最大线程数为 1。这样到了第二次执行任务时,若当前还没执行完,调度器想新开一个线程执行任务,但我们却设置了最大线程数为 1 个(即:没有足够的线程提供给调度器),则调度器会等待当前任务执行完之后,再立即调度执行下一次任务。(注意:此方法仅适用于Quartz中仅有一个Job,如果有多个Job,会影响其他Job的执行)

第二种方法:在 Job 类的头部加上 [DisallowConcurrentExecution],表示禁用并发执行。(推荐使用此方法)

//不允许此 Job 并发执行任务(禁止新开线程执行)
[DisallowConcurrentExecution]
public class Job1 : IJob
{
}
时间: 2024-10-01 04:56:48

小记:Quartz 当 Job 执行时间超过触发间隔时间时所发生的情况的相关文章

跟踪数据库中执行时间超过1.5秒的语句及SP,导入数据库

跟踪 --============================================================================ --新建两个目录 D:\InOut\TraceDB D:\InOut\TraceLog\ --建数据库,建跟踪执行时间超过1.5秒的语句及SP --建作业,每天在固定时间将跟踪文件导入数据库 --======================================================================

【安卓】给gallery内&quot;控件&quot;挂载事件,滑动后抬起手指时也触发事件(滑动时不应触发)的解决、!

思路: 1.gallery内控件挂载事件(如:onClickListener)的方法类似listview,可直接在baseAdapter.getView内给控件挂载(具体方法百度). 2.貌似没问题,但滑动后(手指在挂载了事件的控件上)抬起手指时仍会触发事件,这是不对的. 解决方法时,若为滑动(x有偏移),则在gallery.onInterceptTouchEvent中拦截事件,子控件自然接受不到事件. 注:1>不能简单的判断x有偏移就拦截,有些设备犯贱,即使原地抬起也有可能有偏移,此时本应触发

mysql 对插入超过表字段限制时的处理

mysql在插入时,比如varchar类型超过表字段限制时,经测试不同版本的处理:    5.1版本,会对字符串进行截断后插入,不会报错    5.6,5.7版本,会直接插入失败,并报错

outlook自定义邮件提示声音以及设置接收邮件的间隔时间

outlook自定义邮件提示声音 开始---控制面板---单击声音选项卡---选择声音选项---程序事件下选择---选择新邮件通知---选择浏览你自己要定义的声音文件---确定---OK了!(声音文件需要是wav格式的) 设置outlook接收邮件的时间间隔 工具---选项---邮件设置---发送接受---在安排自动发送接受时间间隔的那栏打勾,并设置相应的时间间隔就OK了! outlook添加一个账户 工具---账户设置---新建--- outlook自定义邮件提示声音以及设置接收邮件的间隔时间

Python3.x:简单时间调度Timer(间隔时间执行)

Python3.x:简单时间调度Timer(间隔时间执行) 代码: import threading import time def fun_timer(): print('hello timer') global timer #重复构造定时器 timer = threading.Timer(5.8,fun_timer) timer.start() #定时调度 timer = threading.Timer(2,fun_timer) timer.start() # 50秒后停止定时器 time.

fping ping 包间隔时间详解

服务器间检查会用到fping的命令,期间遇到了一个问题,需要将ping包间的间隔时间设置为100毫秒,查看fping -h看下,找到了-i和-p两个参数: 看到这两个参数,我当时的表情是这样的: 看不懂,那就测吧: 先来-i: 间隔1s,没有生效.! 再试试-p OK,这个生效了,但-i 和-p的区别是什么?我又尝试了下面的操作: 得出结论: -i 多个目的地址ping包的发送间隔时间 -p 单个IP地址ping包的发送间隔时间 又有一个问题: -i -p是否可以同时使用? 得出结论: 同时使用

Easyui datagrid 设置内容超过单元格宽度时自动换行显示

datagrid 设置内容超过单元格宽度时自动换行显示 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 问题描述 单元格内容超过单元格宽度不会自动化换行.如下: 图1: 图2: 解决方法 定义表格时,设置nowrap属性为false. <table id='tt' class="easyui-datagrid" title="Basic DataGrid" style="width:700px;height:

spring quartz动态修改执行时间

1.获取schedule <bean name="startQuartz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean=&q

一定间隔时间下重复执行一个函数的几个方法

如果有个操作,我们需要过一会儿再做,或者每隔一段时间就要做一次.可以有很多种做法. 独立线程 是的,对.NET Framework本身一知半解的程序员才会使用这种方案.不过,现实中这个方案其实并不少见. public static void Repeat(this Action action, TimeSpan interval) { new Thread(new ThreadStart(() => { while(true) { Thread.Sleep(interval); action()