Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 石英建筑Q-或多或少的工作_Java_Multithreading_Quartz Scheduler - Fatal编程技术网

Java 石英建筑Q-或多或少的工作

Java 石英建筑Q-或多或少的工作,java,multithreading,quartz-scheduler,Java,Multithreading,Quartz Scheduler,我正在将我的Tomcat应用程序转换为使用Quartz调度程序。我使用它主要是在后台触发电子邮件进程,我担心并发作业会使处理器无法承受。所以这是一个最佳实践问题 Q) 生成一个quartz作业(例如每小时一次)并让它连续调用多个例程是否更好?这样,在例行程序1完成之前,例行程序2不会启动 还是将每个例程安排为单独的Quartz作业并限制线程数更好 如果调度了更多线程可用的作业,会发生什么情况。他们只是排队吗?i、 这能成为我的控制机制吗。我已经使用指令来防止并发的相同作业 我不想同时运行三个类似

我正在将我的Tomcat应用程序转换为使用Quartz调度程序。我使用它主要是在后台触发电子邮件进程,我担心并发作业会使处理器无法承受。所以这是一个最佳实践问题

Q) 生成一个quartz作业(例如每小时一次)并让它连续调用多个例程是否更好?这样,在例行程序1完成之前,例行程序2不会启动

还是将每个例程安排为单独的Quartz作业并限制线程数更好

如果调度了更多线程可用的作业,会发生什么情况。他们只是排队吗?i、 这能成为我的控制机制吗。我已经使用指令来防止并发的相同作业

我不想同时运行三个类似的作业。它不依赖于时间,因此串行处理在处理器上更容易实现

最直接的架构是什么

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class HourJob implements Job, InterruptableJob {

    boolean interrupted = false;        
    String cls = this.getClass().getName();

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        System.out.println(cls+"-Start");

        for(int i=1; i<15; i++){            

            try { //do work
                Thread.sleep(1000);
            } catch (InterruptedException e) {  
                e.printStackTrace();
            }

            if(interrupted){
                System.out.println(cls+"-Interrupted");
                return;
            }

        }//for

        System.out.println(cls+"-Exit"); 

    }

    @Override
    public void interrupt() throws UnableToInterruptJobException {
        interrupted = true;     
    }

}


这是一个间接的回答,但我们就是这么做的:
由于我们使用Quartz来安排许多类型的任务,我们不希望某个作业占用太多资源,从而影响其他作业

因此,我们最终拆分了流程:
*Quartz作业只是将数据推送到作业队列中(每种作业类型不同)
*我们配置了执行服务(很容易扩展)从队列中读取数据并执行实际的作业(无论是发送电子邮件还是其他批处理操作)

我们现在有数千个作业在运行时没有并发问题,并且能够轻松地按作业类型进行扩展

  • 从设计的角度来看,如果每个例程在概念上是独立的,我建议将它们作为一个单独的石英作业。这样,如果其中一个在运行过程中出错,其他执行和完成状态将不会受到影响,您将能够在需要时单独应用事件侦听器等。此外,您还将能够独立控制每个侦听器的计划
  • 根据quartz文件:
如果你只有几份一天解雇几次的工作,那么一份 线程很多。如果你有成千上万的工作,有很多 每分钟启动一次,然后你需要一个线程数,比如50或100 (这在很大程度上取决于您工作的性质, 以及您的系统资源

因此,您只能使用一个线程,并将作业调度为使用单独的调度执行,以便它们不会同时触发所有线程

  • 但是,如果同时有多个作业尝试运行,并且您配置的线程数小于这些作业的数量,则找不到线程的线程将被视为未启动:
如果持续触发器错过其点火时间,则会发生失火 因为计划程序正在关闭,或者因为没有 Quartz线程池中用于执行作业的可用线程

请注意,您可以通过更改默认的缺火阈值(30秒)来配置触发器配置为缺火的时间。如果线程在该阈值之前可用,则触发器将在不被视为缺火的情况下执行。另一方面,关于缺火触发器,缺火策略规定了什么将发生:

不同的触发器类型具有不同的缺火指示 对他们可用。默认情况下,他们使用“智能策略”指令- 它具有基于触发器类型和配置的动态行为。 当调度程序启动时,它会搜索任何持久触发器 它会根据它们各自的特性更新它们中的每一个 单独配置的失火说明


每种触发器的默认策略都不同,但它通常会在线程可用时立即运行丢失的触发器。在任何情况下,您都需要查看所使用的触发器的策略,并将其更改为所需的策略

我实际上已经在这样做了。我实际上要控制的是处理队列的作业。今天我要用线程运行它,它变得有点复杂。我不确定我是否完全理解:如果它(过载)在石英中,那么你可以通过设置它的缺火策略(忽略错过的运行、立即运行等)来配置触发器的行为。如果它(过载)在从队列中读取的作业中,这实际上取决于您的应用程序业务逻辑,不是关于Quartz的问题,而是您的队列和应用程序逻辑。太好了!正是我想要的信息。谢谢
public void contextInitialized(ServletContextEvent event) {

...

sched = schedFact.getScheduler();
sched.start();

JobDetail hourJob  = newJob(HourJob.class ).withIdentity("hourJob",  "group1").build();

Trigger hourTrig = newTrigger()  
    .withIdentity("hourTrig", "group1")  
    .withSchedule(cronSchedule("0 0 * * * ?")).build();

sched.scheduleJob(hourJob, hourTrig);
public void contextDestroyed(ServletContextEvent event) {

...

for(JobExecutionContext job : sched.getCurrentlyExecutingJobs()){
    JobKey jK = job.getJobDetail().getKey(); 
    System.out.printf("Inerrupting %s\n", jK.getName());
    sched.interrupt(jK);
}
sched.shutdown(true);