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
{
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Quartz框架来配置时间Quartz是一个功能强大的开源作业调度库,可以让您轻松地定义和调度任务。 要配置时间,首先需要创建一个Trigger对象。Trigger定义了作业何时触发的规则。以下是一些常用的Trigger配置选项: 1. SimpleTrigger:按照指定的时间间隔执行一次或多次作业。 2. CronTrigger:使用Cron表达式定义作业的执行时间表。Cron表达式可以非常灵活地定制作业触发规则,例如每天特定时间执行、每周特定天执行等。 3. CalendarIntervalTrigger:按照指定的日历间隔执行作业。可以指定作业在每天、每周或者每月的特定时间段内执行。 在创建Trigger对象之后,您还需要将其与作业关联起来。作业定义了要执行的任务逻辑。 以下是一个使用Quartz配置时间的示例代码: ```java import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; public class QuartzScheduler { public static void main(String[] args) throws SchedulerException { // 创建一个JobDetail对象,定义要执行的任务逻辑 JobDetail job = JobBuilder.newJob(MyJob.class) .withIdentity("myJob", "group1") .build(); // 创建一个Trigger对象,定义作业触发规则 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) // 每隔10秒执行一次 .repeatForever()) .build(); // 创建Scheduler对象,用于管理作业调度 Scheduler scheduler = new StdSchedulerFactory().getScheduler(); scheduler.start(); scheduler.scheduleJob(job, trigger); } } ``` 在上述示例中,我们使用了SimpleTrigger来定义作业的触发规则,每隔10秒执行一次。您可以根据自己的需求选择合适的Trigger配置选项来配置时间

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值