Quartz.Net线程处理用到的两个Attribute

原文:Quartz.Net线程处理用到的两个Attribute

1.DisallowConcurrentExecution

 加到IJob实现类上,主要防止相同JobDetail并发执行。

 简单来说,现在有一个实现了IJob接口的CallJob,触发器设置的时间是每5s执行一次,但是由于执行过程的时间大于5s,在Quartz scheduler的下一次执行时间到了,那么就会开启另外一个线程执行CallJob,说着有点绕,来点代码吧。

 1                 Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter { Level = Common.Logging.LogLevel.Info };
 2
 3                 IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
 4                 scheduler.Start();
 5                 IJobDetail job = JobBuilder.Create<CallJob>().WithIdentity("calljob", "call")                      .UsingJobData("hello", 0)//先忽略,第二个特性用到                      .Build();
 6                 //触发器
 7                 ITrigger trigger = TriggerBuilder.Create().WithIdentity("calljobtrigger", "call").StartNow().WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever()).Build();
 8                 scheduler.ScheduleJob(job, trigger);
 9                 Thread.Sleep(TimeSpan.FromSeconds(3000));
10                 scheduler.Shutdown();

 1  public class CallJob : IJob
 2     {
 3
 4         public void Execute(IJobExecutionContext context)
 5         {
 6             int i = (int)context.JobDetail.JobDataMap["hello"];//先忽略,第二个特性用到
 7             Console.WriteLine("=====call======"+(i));
 8             Console.WriteLine("call【" + Thread.CurrentThread.ManagedThreadId + "】" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
 9             i++;
10             context.JobDetail.JobDataMap.Put("hello", i);//先忽略,第二个特性用到
11             Thread.Sleep(8000);
12             Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "call执行完毕【" + Thread.CurrentThread.ManagedThreadId);
13
14         }
15     }

  从代码中可以看到我们设置的trrigger是5秒执行一次,在CallJob的Execute中,让线程sleep 8s,这样就能模拟刚才说的情况了,先看下不加DisallowConcurrentExecution的结果

    

  第一张图是不加特性的,第二张图是加上特性的。图一中不难发现,线程10在休眠的时候,由于scheduler规划的trigger已经触发,会立即执行,不去管上次任务是否执行完成,从而出现了同一个Job并行。图二就不会出现并行的情况,当第一次任务还没有执行完成的时候,即使规划的trigger的触发时间到了也不会立即执行,而是等待上次任务完成再执行,依次顺延,保证了相同JobDetail串行。说明一下DisallowConcurrentExecution是禁止相同JobDetail同时执行,而不是禁止多个不同JobDetail同时执行。建议加上该特性,防止由于任务执行时间太长,长时间占用资源,导致其它任务堵塞。

2.PersistJobDataAfterExecution

 加到IJob实现类上,主要表示当正常执行完Job后, JobDataMap中的数据应该被改动, 以被下一次调用时用。还是上面的代码,只是将特性DisallowConcurrentExecution换成了PersistJobDataAfterExecution,特别注意代码中【先忽略】部分。

 当不使用PersistJobDataAfterExecution特性时,每次取出来的hello键值对的value始终都是0,也就是说每次执行 JobDataMap中的数据都是全新的一份,加上特性PersistJobDataAfterExecution之后,就会出现数据共享。没加特性的结果可以看上图,加上之后看下图。

  注意当使用【PersistJobDataAfterExecution】特性时, 为了避免并发时, 存储数据造成混乱, 强烈建议把【DisallowConcurrentExecution】特性也加上。

  本人很菜,欢迎拍砖。

 

原文地址:https://www.cnblogs.com/lonelyxmas/p/12050141.html

时间: 2024-08-30 11:39:50

Quartz.Net线程处理用到的两个Attribute的相关文章

Jmeter 跨线程组传递参数 之两种方法

终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直到登录接口的参数失效了,需再次发送一次登录接口,又可以多次使用其参数,下面举例子: 1.登录接口中利用 Json Path Extractor 获取到登录接口的响应参数,(怎么获取上一节讲过) 终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为

线程通讯和同步的两种实现方法

在多线程编程中,不免要涉及同步和通讯两个方面. 同步有两种方法实现,一种是利用synchronized标示,另外一种是加锁. 生成锁的对象的方法是:private static Lock lock = new ReentrantLock();Lock是一个接口,而Reentrantlock是一个实现的类.构造方法有:ReentrantLock()和ReentrantLock(fair:boolean)两种.其中第二种传递的是一个boolean值的参数,当设置为true时系统会按照等待的先后时间让

Quartz的线程池解析

[org.quartz.core相关类图] 可以看到核心类为QuartzScheduler [QuartzScheduler构造函数] public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval) throws SchedulerException { this.resources = resources; if (resources.

02027_线程池练习:返回两个数相加的结果

1.要求:通过线程池中的线程对象,使用Callable接口完成两个数求和操作. 2.代码实现: (1)Callable接口实现类 1 import java.util.concurrent.Callable; 2 3 public class MyCallable implements Callable<Integer> { 4 // 成员变量 5 int x = 5; 6 int y = 3; 7 8 // 构造方法 9 public MyCallable() { 10 } 11 12 pu

Android之Handler在新线程中读取网络的两种方法

方法一: 创建一个Thread,然后调用start方法. 实例: package com.example.android_handle; import java.io.BufferedInputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import org.apache.http.util.ByteArrayBuffer; import android.app.A

传统的同步线程锁(两)

一. 线程安全 线程安全问题是指程序中公用的东西被多个线程訪问,比方:类的静态变量 线程互斥:是指两个线程之间不能够同一时候执行,他们会互斥,必须等待一个线程执行完成,还有一个才干执行 二. 同步锁 有什么办法能够解决线程安全问题呢?那就是在程序中加锁 Java有两种加锁的方法: 1. 在代码块中加锁 synchronized (this) { ... } 2. 在方法上加锁 public synchronized void xxx(){ ... } 演示样例代码: public class T

tomcat quartz 被触发两次

主要原因为tomcat server.xml 配置问题 <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false"> <Context docBase="/logstat&

Java创建线程的两种方法

大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 创建线程的最简单的方法就是创建一个实现Runnable 接口的类.Runnable抽象了一个执行代码单元.你可以通过实现Runnable接口的方法创建每一个对象的线程.为实现Runnable 接口,一个类仅需实现一个run()的简单方法,该方法声明如下:    public void run( )

Android—— 线程 thread 两种实现方法!(转)

原文地址:http://blog.csdn.net/boyupeng/article/details/6208072 这篇文章中有三点需要提前说明一下, 一: 在android中有两种实现线程thread的方法: 一种是,扩展java.lang.Thread类 另一种是,实现Runnable接口 二:Thread类代表线程类,它的两个最主要的方法是: run()——包含线程运行时所执行的代码 Start()——用于启动线程 三: Handler 机制,它是Runnable和Activity交互的