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

室内设计装修网站网店首页设计

室内设计装修网站,网店首页设计,nofollow外链对于网站有提升吗,建设主题网站一般要经历的顺序​ 我们在前面文章中说到过Quartz涉及到的线程,但是散落在几篇文章中,不好找。而Quartz涉及到的线程对于理解Quartz也比较重要,所以今天专门提取出来单独说一下。 Quartz中的主要线程: 任务调度线程QuartzSchedulerThread 任务执…


我们在前面文章中说到过Quartz涉及到的线程,但是散落在几篇文章中,不好找。而Quartz涉及到的线程对于理解Quartz也比较重要,所以今天专门提取出来单独说一下。

Quartz中的主要线程:

  1. 任务调度线程QuartzSchedulerThread

  2. 任务执行线程

  3. Misfire处理线程

  4. ClusterManager线程

任务调度线程 QuartzSchedulerThread

QuartzSchedulerThread是任务调度线程,他的职责是对满足触发条件(nextFireTimer到了)的注册到JobStore的Trigger分配给可用的任务执行线程去执行。

QuartzSchedulerThread启动

任务调度线程QuartzSchedulerThread是在调度器Scheduler创建的时候启动的。

应用层通过以下调用创建Scheduler:


Scheduler sche = new StdSchedulerFactory().getScheduler();

一般情况下通过StdSchedulerFactory构建Scheduler,getScheduler首先尝试从SchedulerRepository获取Schedule,首次运行获取不到,则通过instantiate()方法获取。

public Scheduler getScheduler() throws SchedulerException {if (cfg == null) {initialize();}SchedulerRepository schedRep = SchedulerRepository.getInstance();Scheduler sched = schedRep.lookup(getSchedulerName());if (sched != null) {if (sched.isShutdown()) {schedRep.remove(getSchedulerName());} else {return sched;}}	sched = instantiate();return sched;
}

instantiate()方法特别特别特别长,几乎就是在这里完成Quartz所有相关组件的初始化的。

其中会创建QuartzScheduler,之后会将QuartzScheduler包装到stdScheduler中存入SchedulerRepository中。

instantiate()创建QuartzScheduler是调用的构造方法:

public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval)throws SchedulerException {this.resources = resources;if (resources.getJobStore() instanceof JobListener) {addInternalJobListener((JobListener)resources.getJobStore());}this.schedThread = new QuartzSchedulerThread(this, resources);	ThreadExecutor schedThreadExecutor = resources.getThreadExecutor();schedThreadExecutor.execute(this.schedThread);if (idleWaitTime > 0) {	this.schedThread.setIdleWaitTime(idleWaitTime);}jobMgr = new ExecutingJobsManager();addInternalJobListener(jobMgr);errLogger = new ErrorLogger();addInternalSchedulerListener(errLogger);signaler = new SchedulerSignalerImpl(this, this.schedThread);getLog().info("Quartz Scheduler v." + getVersion() + " created.");
}

可以看到构造方法中创建了QuartzSchedulerThread对象,之后获取ThreadExecutor(一般情况下为DefaultThreadExecutor)并通过调用其execute方法启动QuartzSchedulerThread线程:


public class DefaultThreadExecutor implements ThreadExecutor {public void initialize() {}public void execute(Thread thread) {thread.start();}}
QuartzSchedulerThread的运行

其实就是他的run方法,我们也大概分析过,其主要逻辑是:

  1. 从作业执行线程池获取availThreadCount,也就是当前可用的线程数

  2. 调用JobStore的acquireNextTriggers方法,获取特定短时间(idleWaitTime,默认30秒)内可能需要被触发的,数量不超过availThreadCount的触发器

  3. 调用JobStore的triggersFired方法对获取到的可能需要被触发的触发器进行二次加工,再次获取到最终的待触发器结果集

  4. 循环处理最终的待处理触发器结果集中的每一个需要被触发的触发器

  5. 用JobRunShell包装该触发器,送给线程池执行该触发器关联的作业

好了,作业调度线程QuartzSchedulerThread我们就基本搞清楚了。

作业执行线程

Quartz的作业执行线程是放在线程池中进行管理的,默认是SimpleTreadPool,有关SimpleThreadPool我们前面专门有一篇文章介绍过,这里就不再赘述了。

作业执行线程和作业调度线程一样,也是在作业调度器Scheduler创建后立即启动,这个过程同样也是在StdSchedulerFactory的instantiate()方法中完成的:

instantiate()创建SimpleThreadPool之后会调用SimpleThreadPool的initialize方法,根据配置文件指定的任务执行线程数完成工作线程的初始化和启动。比如配置文件设置为10则初始化10个工作线程并逐个启动。作业执行线程的初始化及启动的详细过程请参考Quartz - SimpleThreadPool。

MisfireHandler线程

如果你的项目使用RAMJobStore,而不是JDBC-based JobStore(指需要持久化到数据库的JobStore),那么就不存在Misfire处理线程。

因为RAMJobStore在处理正常触发的过程中顺便就处理了Misfire,所以就不再需要其他处理机制了,这部分我们在前面的文章中也分析过Quartz - Misfire (for RAMJobstore)。

JDBC-based JobStore在处理正常触发的时候只获取未错过触发时间的触发器,对于错过触发时间的、也就是Misfire的触发器就需要另外的机制来处理。

Misfire处理线程就是Quartz采用JDBC-based JobStore的情况下用来处理错过触发时机的触发器的线程。

MisfireHandler启动

MisfireHandler定义在JobStoreSupport类中,JobStoreSupport是JobStore的JDBC-based JobStore的虚拟类,Quartz主要提供了两个基于JDBC的JobStore的实现:JobStoreTX、JobStoreCMT。JDBC-based JobStore详细内容请参考Quartz - JDBC-Based JobStore,今天主要分析MisfireHandler。

我们在应用中创建任务调度器Scheduler后需要调用他的start方法:

	Scheduler sche = new StdSchedulerFactory().getScheduler();sche.scheduleJob(jobDetail,trigger);sche.start();

这个start方法会调用到JobStore的schedulerStarted()方法,如果我们应用中采用的是JDBC-based JobStore的话,会调用到JobStoreSupport的schedulerStarted(),其中会创建MisfireHandler之后调用MisfireHandler的initialize():

	misfireHandler = new MisfireHandler();if(initializersLoader != null)misfireHandler.setContextClassLoader(initializersLoader);misfireHandler.initialize();

Misfire的initialize将创建好的MisFireHandle线程交给ThreadExecutor启动。

	public void initialize() {ThreadExecutor executor = getThreadExecutor();executor.execute(MisfireHandler.this);}
MisfireHandle的运行

也就是MisfireHandle的run方法。处理逻辑和RAMJobStore处理misfired trigger的逻辑类似,只不过MisfireHandle的所有处理逻辑都是通过数据库操作完成的。

JDBC-Based JobStore对应的表结构我们会找机会专门分析,这里就不详细展开了。

MisfireHandle的run方法的主要逻辑为:

  1. 从数据库中获取在WAITING(等待执行)状态、下次执行时间小于msifiredtime(当前时间 - MisfireThreshold)的触发器,也就是错过触发时间的触发器

  2. 为了避免存在大量misfired trigger的情况下,一次处理太多数据影响其他正常触发器的执行,MisfireHandle线程每次仅获取部分而不是全部misfired trigger(参数maxToRecoverAtATime指定,默认为20)

  3. 对获取到的每一个错过执行时间的触发器(misfired trigger),调用触发器的updateAfterMisfire方法获取下次执行时间,updateAfterMisfire方法我们在上一篇讲Misfire处理策略的文章中说过,就是根据触发器的处理策略获取下次执行时间

  4. updateAfterMisfire方法执行后,获取到的触发器的下次执行时间如果不为空的话,更新到数据库中,等待正常的任务执行线程调度执行

ClusterManager线程

与MisfiredHandle一样,ClusterManager线程也是JDBC-Based JobStore特有的。

顾名思义,ClusterManager线程与集群有关系,JDBC-Based JobStore是可以支持Quartz的集群部署的,在集群环境下,Quartz服务节点可能会down机、掉线,从而影响任务的执行,ClusterManager线程就是负责检查Quartz服务节点的在线状态的,如果发生掉线后,将该服务节点负责的触发器交给其他服务节点来处理。

具体逻辑等到我们分析完Quartz Cluster之后补充。

http://www.yayakq.cn/news/619973/

相关文章:

  • 青岛高端网站建设高要建设网站
  • 自己做网站怎么赚钱营口网站建设公司
  • 网站分成推广怎么做网络营销推广方案创意
  • 电商网站开发用什么语言表达wordpress二次元
  • 济南网站制作方案实惠的福州网络推广
  • 营销型网站跟云网站常州城乡建设局网站
  • 旅游景点网站建设建筑工程网名
  • 外贸销售网站有哪些西安微网站建设
  • 公司网站点击量如何看用手机怎么制作动漫视频
  • 怎么创立自己的网站南京市住房和城乡建设部网站
  • 那些网站可以够买域名电商网站的支付功能
  • 网站建设合同服务响应时间山姆超市网上购物网
  • 做软件赚钱的网站有哪些免费建设com网站
  • 电子商务网站建设是什么意思校园门户网站开发需求
  • 建一个网站需要什么流程wordpress显示股价
  • 哈尔滨做网站哪好公司注册后每年的费用
  • 网站做sem优化唯美个人网站欣赏
  • 石家庄好用的招聘网站织梦后台怎么加自己做的网站
  • 上高做网站公司免费个人简历表
  • 做app网站WordPress更换主题残留
  • 如何学做网站html网站怎么做的
  • 网站文案案例开封网站制作哪家好
  • 做网站容易找工作吗响应式网站一般做几个版本
  • 做地方网站需要什么部门批准学做网站基础知识
  • 互联网公司的招聘信息东莞网站优化seo
  • 百色网站优化百度经验网站建设
  • 优化网站搜索许嵩做的网站
  • 电子商务网站建设策划青岛网络优化公司
  • 网站开发包括哪些工作帮别人做网站 别人违法
  • appcms程序怎么做网站简单网站的代码