quartz的核心接口如下:

接口 含义
Scheduler scheduler的主要API接口
Job 任务实现接口,期望调度器能够执行
JobDetail 用于定义Job实例
Trigger 调度器基于特定时间来执行指定任务的组件
JobBuilder   用于定义、创建JobDetail实例
TriggerBuilder 用于定义、创建Trigger实例

1. Scheduler

一个调度器的生命周期为通过SchedulerFactory创建,直到执行其shutdown()方法。当Scheduler创建之后,可以进行增加、删除及显示任务Job与触发器Trigger,并且执行其他的调度相关的操作,如暂停一个触发器Trigger。需要注意的是,直到调用start()方法时,Scheduler才正式开始执行job和trigger。

StdSchedulerFactory用于创建Scheduler,其依赖于一系列的属性来决定如何产生Scheduler。可以通过四种途径向StdSchedulerFactory提供属性配置信息。

1) 通过java.util.Properties实例提供

  1. package org.ws.quartz.test2;
  2.  
  3. import java.util.Properties;
  4.  
  5. import org.quartz.Scheduler;
  6. import org.quartz.SchedulerException;
  7. import org.quartz.impl.StdSchedulerFactory;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10.  
  11. public class SchedulerExample {
  12.  
  13. private static Logger logger = LoggerFactory.getLogger(SchedulerExample.class);
  14.  
  15. public static void main(String[] args) {
  16. // 创建工厂实例
  17. StdSchedulerFactory factory = new StdSchedulerFactory();
  18.  
  19. // 创建配置工厂的属性对象
  20. Properties props = new Properties();
  21. props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, "org.quartz.simpl.SimpleThreadPool"); // 线程池定义
  22. props.put("org.quartz.threadPool.threadCount", "10"); // 默认Scheduler的线程数
  23.  
  24. try {
  25. // 使用定义的属性初始化工厂
  26. factory.initialize(props);
  27.  
  28. Scheduler scheduler = factory.getScheduler();
  29.  
  30. scheduler.start();
  31. logger.info("scheudler started, metadata: "+scheduler.getMetaData());
  32. } catch (SchedulerException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }

执行后的结果:

  1. 2017-07-09 15:15:17 [INFO]-[org.ws.quartz.test2.SchedulerExample] scheudler started, metadata: Quartz Scheduler (v2.2.1) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
  2. Scheduler class: 'org.quartz.impl.StdScheduler' - running locally.
  3. Running since: Sun Jul 09 15:15:17 CST 2017
  4. Not currently in standby mode.
  5. Number of jobs executed: 0
  6. Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  7. Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

可以看到对应的配置属性已经生效。

通过Properties设置工厂属性的缺点在用硬编码,假如需要修改例子中线程数量,将不得不修改代码,然后重新编译。后面几种方法可以解决硬编码的问题。

2) 通过外部属性文件提供

使用方法:

  1. public void initialize(String filename) throws SchedulerException;

3) 通过含有属性文件内容的java.io.InputStream提供

使用方法:

  1. public void initialize(InputStream propertiesStream) throws SchedulerException;

4) quartz.properties配置文件【推荐】

如果调用无参的initialize方法,StdSchedulerFactory会试图从quartz.properties的文件中加载。quartz.properties相关配置后续文章会介绍,注意quartz.properties的加载顺序为:

a. 检查System.getProperty("org.quartz.properties")中是否设置其他属性文件名

b. 如果a未设置,则将会从当前工作目录中加载quartz.properties配置文件

c. 如果b未找到,则试图从系统的classpath中加载该配置文件。

Scheduler在生命周期中也可执行其他操作,如查询、设置standby模式、继续执行、停止执行。standby模式会导致Scheduler暂时停止查找Job去执行。standby模式的设置直接使用scheudler.standby()即可。

Scheduler的停止方法为shutdown()方法,也可以使用有参shutdown(false),其中参数表示是否让当前正在进行的job正常执行完成才停止Scheduler。

2. Job

Job即为为你执行一个任务的Java类。该任务可以是java编码的任何功能,如使用JavaMail发送邮件、创建远程接口并调用EJB上的方法等。

Java类仅需要实现org.quartz.job接口,将所需要实现的功能放在其execute方法中。execute方法的定义如下:

  1. public void execute(JobExecutionContext context) throws JobExecutionException;

其中JobExecutionContext对象让Job能访问Quartz运行时环境的所有信息和Job本身的明细数据。运行时环境信息包括注册到Scheduler上与该Job相关联的JobDetail和Trigger。

例:Quartz使用(1) - 初识quartz示例中HelloWordJob获取运行环境时信息如下:

  1. package org.ws.quartz.test1;
  2.  
  3. import org.quartz.Job;
  4. import org.quartz.JobDetail;
  5. import org.quartz.JobExecutionContext;
  6. import org.quartz.JobExecutionException;
  7. import org.quartz.Scheduler;
  8. import org.quartz.SchedulerException;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11.  
  12. public class HelloWorldJob implements Job{
  13.  
  14. private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);
  15.  
  16. @Override
  17. public void execute(JobExecutionContext context) throws JobExecutionException {
  18.  
  19. logger.info("Hello World");
  20.  
  21. // 每一个Job都有其自己所属的JobDetail
  22. JobDetail jobDetail = context.getJobDetail();
  23.  
  24. // JobDetail的名称和组名
  25. logger.info("Name and Group: "+jobDetail.getKey());
  26.  
  27. // 获取Scheduler
  28. Scheduler scheduler = context.getScheduler();
  29. try {
  30. logger.info("Scheduler name: "+scheduler.getSchedulerName());
  31. } catch (SchedulerException e) {
  32. e.printStackTrace();
  33. }
  34.  
  35. logger.info("job class: "+jobDetail.getJobClass());
  36.  
  37. // 任务执行的时间
  38. logger.info("Job fired at "+context.getFireTime());
  39.  
  40. // 任务下一次执行的时间
  41. logger.info("Job nexe fire time: "+context.getNextFireTime());
  42. }
  43. }

运行结果如下:

  1. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] init scheduler componets
  2. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] execute scheduler
  3. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  4. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  5. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  6. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  7. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:00:59 CST 2017
  8. 2017-07-09 16:00:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:09 CST 2017
  9. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  10. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  11. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  12. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  13. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:09 CST 2017
  14. 2017-07-09 16:01:09 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:19 CST 2017
  15. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  16. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  17. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  18. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  19. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:19 CST 2017
  20. 2017-07-09 16:01:19 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:29 CST 2017
  21. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  22. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  23. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  24. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  25. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:29 CST 2017
  26. 2017-07-09 16:01:29 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:39 CST 2017
  27. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  28. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  29. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  30. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  31. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:39 CST 2017
  32. 2017-07-09 16:01:39 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:49 CST 2017
  33. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  34. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  35. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  36. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  37. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:49 CST 2017
  38. 2017-07-09 16:01:49 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:01:59 CST 2017
  39. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World
  40. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Name and Group: HelloWorld_Group.HelloWorld_Job
  41. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Scheduler name: DefaultQuartzScheduler
  42. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] job class: class org.ws.quartz.test1.HelloWorldJob
  43. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job fired at Sun Jul 09 16:01:59 CST 2017
  44. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Job nexe fire time: Sun Jul 09 16:02:09 CST 2017
  45. 2017-07-09 16:01:59 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] shut down scheduler

3. JobDetail

3.1 Job简述

JobDetail是作为Job实例进行定义的,注意部署在Scheduler上的每一个Job只创建一个JobDetail实例。且需要注意的是注册到Scheduler上的不是Job对象,而是JobDetail实例。

Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。

可以使用JobDataMap来定义Job的状态,JobDataMap中可以存入key-value对,这些数据可以在Job实现类中进行传递和访问。这是向你的Job传送配置信息的便捷方法。

Job 能通过 JobExecutionContext 对象访问 JobDataMap

例:在Quartz使用(1) - 初识quartz示例中,可以在等待时间修改为20s, SimpleQuartzExample.createJobDetail方法修改为:

  1. protected JobDetail createJobDetail(){
  2. return JobBuilder.newJob(HelloWorldJob.class) // 待执行的任务
  3. .withIdentity("HelloWorld_Job", "HelloWorld_Group") // 名称与组名组成Scheduler中任务的唯一标识
  4. .usingJobData("message", "welcom to study quartz") // 存储Job的状态信息
  5. .build(); // 构建
  6. }

同时HelloWorldJob中的execute方法修改如下:

  1. public void execute(JobExecutionContext context) throws JobExecutionException {
  2. logger.info("Hello World, "+context.getJobDetail().getJobDataMap().get("message"));
  3. }

执行结果:

  1. 2017-07-09 16:17:51 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] init scheduler componets
  2. 2017-07-09 16:17:51 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] execute scheduler
  3. 2017-07-09 16:17:51 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World, welcom to study quartz
  4. 2017-07-09 16:18:01 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World, welcom to study quartz
  5. 2017-07-09 16:18:11 [INFO]-[org.ws.quartz.test1.HelloWorldJob] Hello World, welcom to study quartz
  6. 2017-07-09 16:18:11 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] shut down scheduler

3.2 有状态Job和无状态Job

有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态job每次调用时都会创建一个新的JobDataMap。

有状态的Job示例:

调度主方法:

  1. package org.ws.quartz.test1;
  2.  
  3. import org.quartz.JobBuilder;
  4. import org.quartz.JobDetail;
  5. import org.quartz.Scheduler;
  6. import org.quartz.SchedulerException;
  7. import org.quartz.SimpleScheduleBuilder;
  8. import org.quartz.Trigger;
  9. import org.quartz.TriggerBuilder;
  10. import org.quartz.impl.StdSchedulerFactory;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13.  
  14. public class SimpleQuartzExample {
  15.  
  16. private static Logger logger = LoggerFactory.getLogger(SimpleQuartzExample.class);
  17.  
  18. public static void main(String[] args) throws SchedulerException, InterruptedException {
  19.  
  20. SimpleQuartzExample exam = new SimpleQuartzExample();
  21.  
  22. logger.info("init scheduler componets");
  23.  
  24. // 创建任务
  25. JobDetail jobDetail = exam.createJobDetail();
  26.  
  27. // 创建触发器
  28. Trigger trigger = exam.createTrigger();
  29.  
  30. // 创建调度器
  31. Scheduler scheduler = exam.createScheduler();
  32.  
  33. // 构建调度任务
  34. scheduler.scheduleJob(jobDetail, trigger);
  35.  
  36. logger.info("execute scheduler");
  37. // 开启调度器
  38. scheduler.start();
  39.  
  40. // 一分钟后关闭调度器
  41. Thread.sleep(20000);
  42. scheduler.shutdown();
  43.  
  44. logger.info("shut down scheduler");
  45. }
  46.  
  47. protected Scheduler createScheduler() throws SchedulerException{
  48. return StdSchedulerFactory.getDefaultScheduler();
  49. }
  50.  
  51. protected JobDetail createJobDetail(){
  52. return JobBuilder.newJob(HelloWorldJob.class) // 待执行的任务
  53. .withIdentity("HelloWorld_Job", "HelloWorld_Group") // 名称与组名组成Scheduler中任务的唯一标识
  54. .usingJobData("count", 0) // 将count初始化为0
  55. .build(); // 构建
  56. }
  57.  
  58. protected Trigger createTrigger(){
  59. return TriggerBuilder.newTrigger()
  60. .withIdentity("HelloWorld_Trigger", "HelloWorld_Group") // 名称与组名组成Scheduler中触发器的唯一标识
  61. .withSchedule(
  62. SimpleScheduleBuilder.simpleSchedule() // 创建SimpleTrigger
  63. .withIntervalInSeconds(10) // 10秒间隔
  64. .repeatForever() // 重复循环
  65. ).build(); // 构建
  66. }
  67. }

HelloWorldJob方法:

  1. package org.ws.quartz.test1;
  2.  
  3. import org.quartz.Job;
  4. import org.quartz.JobDataMap;
  5. import org.quartz.JobExecutionContext;
  6. import org.quartz.JobExecutionException;
  7. import org.quartz.PersistJobDataAfterExecution;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10.  
  11. @PersistJobDataAfterExecution
  12. public class HelloWorldJob implements Job{
  13.  
  14. private static Logger logger = LoggerFactory.getLogger(HelloWorldJob.class);
  15.  
  16. @Override
  17. public void execute(JobExecutionContext context) throws JobExecutionException {
  18. JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
  19.  
  20. int count = jobDataMap.getInt("count");
  21. logger.info("count: "+count);
  22.  
  23. ++count;
  24. jobDataMap.put("count", count);
  25. }
  26. }

执行结果:

  1. 2017-07-09 16:38:55 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] init scheduler componets
  2. 2017-07-09 16:38:55 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] execute scheduler
  3. 2017-07-09 16:38:55 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 0
  4. 2017-07-09 16:39:05 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 1
  5. 2017-07-09 16:39:15 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 2
  6. 2017-07-09 16:39:15 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] shut down scheduler

如果不增加@PersistJobDataAfterExecution注解,运行结果为:

  1. 2017-07-09 16:40:58 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] init scheduler componets
  2. 2017-07-09 16:40:59 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] execute scheduler
  3. 2017-07-09 16:40:59 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 0
  4. 2017-07-09 16:41:08 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 0
  5. 2017-07-09 16:41:18 [INFO]-[org.ws.quartz.test1.HelloWorldJob] count: 0
  6. 2017-07-09 16:41:19 [INFO]-[org.ws.quartz.test1.SimpleQuartzExample] shut down scheduler

可见 @PersistJobDataAfterExecution的作用在于持久化保存在JobDataMap中的传递参数,使得多次执行Job,可以获取传递参数的状态信息。

3.3 @DisallowConcurrentExecution

quartz中另一个常用的注解为@DisallowConcurrentExecution,该注解可以同一个时刻,同一个任务只能执行一次,不能并行执行两个或多个同一任务。但需要注意的是,多个不同的任务是可以同时执行的。

Quartz使用(2) - Quartz核心接口Scheduler、Job的更多相关文章

  1. Quartz框架学习(1)—核心层次结构

    Quartz框架学习 Quartz(任务调度)框架的核心组件: job:任务.即任务调度行为中所要调度的对象. trigger:触发器.是什么促使了一个任务的调度?当然是时间.这也算事件驱动类型程序. ...

  2. (转)Java任务调度框架Quartz入门教程指南(三)任务调度框架Quartz实例详解深入理解Scheduler,Job,Trigger,JobDetail

    http://blog.csdn.net/zixiao217/article/details/53053598 首先给一个简明扼要的理解: Scheduler 调度程序-任务执行计划表,只有安排进执行 ...

  3. 实现quartz定时器及quartz定时器原理介绍(转)

    一.核心概念 Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可.1.Job表示一个工作,要执行的具体内容.此接口中只有一个方法void execute(Job ...

  4. quartz (一) 基于 Quartz 开发企业级任务调度应用

    本文转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/ Quartz 基本概念及原理 Quartz Scheduler 开 ...

  5. Quartz使用(6) - Quartz项目实战

    本片博文将阐述项目工作中使用Quartz的情况,包含项目背景.项目框架.Quartz集群部署等方面,重点讲述如何在实际项目中使用Quartz. 1. 背景 因项目需求,需要定时调用数据下载接口,并将数 ...

  6. 【Quartz.NET】Quartz.NET 入门

    概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了 ...

  7. Net作业调度(一) -Quartz.Net入门 Quartz表达式生成器 [转]

    背景 很多时候,项目需要在不同个时刻,执行一个或很多个不同的作业. Windows执行计划这时并不能很好的满足需求了. 这时候需要一个更为强大,方便管理,集部署的作业调度了. 介绍 Quartz一个开 ...

  8. Quartz使用(5) - Quartz的Job存储及集群部署

    1. Job的存储与持久化 Quartz的JobStore接口定义了作业Job.触发器trigger.调度器Scheduler等数据存储机制.Quartz主要有两种Job存储类型:内存存储RAMJob ...

  9. 定时组件quartz系列<二>quartz的集群原理

    1.基本信息:      Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2Se和J2EE应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它 来为执行一个作业而创建简单的或 ...

随机推荐

  1. .NET 一般处理程序使用Session

    .ashx中引用 session必须 using System.Web.SessionState ,继承IReadOnlySessionState/IRequiresSessionState IRea ...

  2. ueditor UEditor的setContent的时候报错

    今天在使用UEditor的setContent的时候报错,报错代码如下 TypeError: me.body is undefined 或 Uncaught TypeError: Cannot set ...

  3. STM32单片机串口中断+DMA使用(含CUBE配置)

    最近又要重新用32做点东西,发现一两年没怎么碰的结果就是,曾经熟得不行的东西都变得极度陌生,这种重新学习记忆的过程过于痛苦,果然还是要留下一些记录给之后失忆的自己的. 1.STM32CUBE配置 1. ...

  4. Codeforces Round #538 (Div. 2)D(区间DP,思维)

    #include<bits/stdc++.h>using namespace std;int a[5007];int dp[5007][5007];int main(){    int n ...

  5. Git 分支管理-git stash 和git stash pop

    https://blog.csdn.net/u010697394/article/details/56484492 合并分支,冲突是难免的,在实际协作开发中我们遇到的情况错综复杂,今天就讲两个比较重要 ...

  6. P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队

    \(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...

  7. c++构造函数问题,初始化和赋值问题

    默认构造函数(就是没有参数的构造函数) The Default ConstructorThe default constructor is the constructor used to create ...

  8. HDU6298 Maximum Multiple (多校第一场1001)

    Maximum Multiple Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. 【STL基础】vector

    vector 构造函数: //default: vector<T> v; //空的vector //fill: vector<T> v(n); //n个元素的vector,元素 ...

  10. Go语言基础之12--Channel

    一.不同goroutine之间如何进行通讯? 1.全局变量和锁同步 缺点:多个goroutine要通信时,定义太多的全局变量(每个全局变量功能不一样),不好维护 2.Channel 二.channel ...