【问题标题】:How to limit number of job instance of particular class concurrent execution in quartz scheduler?如何限制石英调度程序中特定类并发执行的作业实例数?
【发布时间】:2014-11-03 17:19:29
【问题描述】:

我有一个实现 Job 的“Applier”类。 表示“Applier”类是 Quartz Job 的实例之一。

我的要求是控制一次执行的“Applier”实例的数量。 意味着我想限制,比如一次最多执行 5 个“Applier”实例。 如果“Applier”的第 6 个实例来了,并且 5 个实例已经在执行,那么它必须等到“Applier”的一个实例完成。

Quartz 调度器中是否有任何等待/通知类型机制。意味着如果作业的第 6 个实例尝试运行并且已经执行的 5 个实例比第 6 个实例必须等待并在 5 个实例执行完成后通知。

意味着我想为 Job 的特定实例实现一些 ThreadPool 类型的机制。 我不希望 Quartz Scheduler 级别的 ThreadPool Like mechanisum b'coz 它已经由 Quartz Scheduler 提供。

【问题讨论】:

  • 我的案例是多个石英作业作业到单个作业(石英类)的情况。 JOB(Quartz Job) -> Job(Quartz class) 多对一 我已将所有“Applier”类放在同一个组中。我也将触发器放在同一组中。我尝试使用 JobListner 进行控制,但 Quartz 的“调度程序”类的“pauseJob”不适用于仅安排 1 次执行的 JOB。我找不到任何可以“暂停”执行特定组的机制。我也检查了“JobFactory”,但在我的情况下也没有用。

标签: quartz-scheduler quartz.net


【解决方案1】:

我不确定您是否知道这一点,但所有工作都是 jobkey 独有的。

让我们从这个答案的约定开始

JOB -- 这意味着石英工作

Job -- Quartz 作业类

正如我之前提到的,JOB 只能有一个实例。这是怎么回事,每个 JOB 都由一个 jobkey 定义,现在 jobkey 总是唯一的

这意味着通常您在 JOB 和 Job 之间具有一对一的映射,即一个计划的作业(QuartZ 作业和实现接口 Job 的类

这是工作 -> 工作

案例 1

多个作业实例而不是多个作业实例

看起来像

工作 A -> 工作 |

JOB B -> Job |...........多个 JOB 运行同一个类

工作 C -> 工作 |

只需在同一个作业组中保留不同的作业密钥,您就可以将多个作业实例加载到您的调度程序中

看看JobFactory 因为

JobFactory 负责生成 Job 类的实例。

..

案例 2

现在介绍 JOB 实例。根据您的日程安排和 JOB 的执行时间,可以有多个实例并行运行(调用它是不合适的,因为多个实例更好的术语是并发执行)。为避免这种情况,您将不得不编写一些自定义逻辑。 或者使用注解DisallowConcurrentExecution

加载 5 个具有 DisallowConcurrentExecution 的作业实例,如案例 1 所示。但这将意味着 5 个不必要的实例,即使一次可能不需要该作业。

案例 3

现在让我们考虑设置一个初始化为 1 的标志。可以帮助处理此问题的自定义逻辑

在你开始工作之前。您可以检查 flag 是否小于 5。如果小于 5,则进入主业务逻辑并增加 flag 的值。执行结束后,在退出块之前将其递减。这样,即使您有多个 JOB 实例正在运行,业务逻辑也不会被执行。

    private static int jobRunningFlag = 0;

    @Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    if(JobName.jobRunningFlag <= 5)
        {
            JobName.jobRunningFlag++
    .....execute this piece of code....
            JobName.jobRunningFlag--
    }
}

显然 jobRunningFlag 将是存储在同一个 Job 类中的静态变量

PS: 对此的更多答案将基于您的 cmets。您是否查看过 JobFactory 和相关的类/接口。你试过什么。我的想法是这将完全归结为您的实现逻辑。我对石英不太了解。

【讨论】:

  • 我的案例是多个石英作业作业到单个作业(石英类)的情况。 JOB(Quartz Job) -> Job(Quartz class) 多对一 我已将所有“Applier”类放在同一个组中。我也将触发器放在同一组中。我尝试使用 JobListner 进行控制,但 Quartz 的“调度程序”类的“pauseJob”不适用于仅安排 1 次执行的 JOB。我找不到任何可以“暂停”执行特定组的机制。我也检查了“JobFactory”,但在我的情况下也没有用。 JobFactory 实现类没有为“暂停”方法提供任何特殊机制。
  • 我也想办法解决这个问题。您也许可以查看 EJB 调度程序。或者归结为像 CASE 3 这样的诡计游戏,这意味着自定义逻辑。我将更新我的答案的一些内容尝试查看它们
  • 在进入执行方法调用时,首先检查作业是否针对存储在其中的标志变量和值。并将作业的实际执行移到条件逻辑中
  • 我尝试使用线程的“等待”和“通知”机制解决问题,并在一定程度上解决问题。但这种机制的缺点是,如果有 100 个“对象”等待锁定,则比 JVM 堆内存增加。表示 JVM 堆内存将随着等待对象数量的增加而增加。
  • 有趣。我认为您不是在创建计划的作业,您只是在尝试生成线程。请提及您的工作按什么时间表运行。您正在使用什么堆大小。在什么情况下你会得到 100 个对象。你有很多你似乎没有提到的限制。
【解决方案2】:

您可以限制并发运行的作业数量(线程池),也可以将给定的作业实例限制为仅一个并发实例。您不能将给定作业限制为仅给定数量的实例(1 个除外)。做你想做的事情的唯一方法是只为给定的调度程序运行一种作业,然后将线程池限制为你想要在同一时间运行的作业数

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    相关资源
    最近更新 更多