㈠ 用java的Quartz包定時調用方法,我想實現每隔半小時調用一次方法,那個配置文件中時間的配置符號咋寫的了
<!-- 常用的corn表達式
*隔5秒執行一次:*/5 * * * * ?
*隔1分鍾執行一次:0 */1 * * * ?
*23點執行一次:0 0 23 * * ?
*晨1點執行一次:0 0 1 * * ?
*月1號凌晨1點執行一次:0 0 1 1 * ?
*月最後一天23點執行一次:0 0 23 L * ?
*周星期天凌晨1點實行一次:0 0 1 ? * L
*在26分、29分、33分執行一次:0 26,29,33 * * * ?
*的0點、13點、18點、21點都執行一次:0 0 0,13,18,21 * * ?
-->
這是spring調用時,的符號公式
㈡ 定時器(quartz 一)
優點:與spring集成、動態添加任務、支持集群
缺點:不支持分布式(只能一個任務在一台伺服器上執行,不能分片)
將一個任務拆分成多個獨立的任務項,由分布式的伺服器分別執行某一個或幾個分片項。而傳統的定時器任務都在一台伺服器上執行,如果數據很大那麼壓力很大。
舉例:處理一百萬的訂單:A伺服器處理尾數偶數的訂單,B伺服器處理尾數奇數的訂單。
整合java項目
1、引入quartz 依賴
2、quartz.properties
3、
注意:
1、每一個job執行都是一個新的線程(即使是同一個任務,這個elastic-job不同)但是如果在配置文件quartz.properties中配置的線程消耗完,也還是會陷入阻塞的。根據業務來預估線程池的大小。(所以的任務共享一個線程池)
2、每一個job執行都會創建一個新的job對象,所以想通過job的成員變數來傳遞信息是不可行的(每次都會初始化)
3、myJob類必須要有空的構造方法
1、方式1:在創建jobDetail是傳遞JobDataMap,然後通過JobExecutionContext獲取JobDataMap
2、方式2:在myjob中定義成員變數,並生成get,set方法
上面我們知道任務間都是並發處理的,那麼要考慮並發安全問題。
1、使用@DisallowConcurrentExecution
使用@PersistJobDataAfterExecution註解和jobDataMap.put方法
1、startTime屬性:設置trigger第一次觸發的時間
2、endTime屬性:表示trigger的失效時間點
3、優先順序(priority)當多個Trigger並發執行,但是線程不夠時觸發,會優先執行級別高的Trigger
TriggerBuilder.newTrigger().withPriority(10);
默認時5,數字越大優先順序越高
4、錯過觸發(misfire instructions)
1、策略:錯過了什麼都不做,等待下一次觸發時間
設置每5秒執行一次,任務7秒。
發現這樣是不會生效的,因為內部判斷了一下錯過的時間是否大於misfireThreshold這個值(默認5秒),如果小於還是立即執行。這里我們只失效了2秒,是小於5秒的。
通過quartz.properties設置misfireThreshold的值
這樣再運行,發現策略生效了。
2、策略:錯過立即執行
5、日歷(calendar)
1、可以在具體的時間點執行一次
2、可以按照指定間隔時間重復若干次
1、使用cron表達式觸發
, 代表並且,如果10,20 10秒和20秒都指向
? 只能出現在日期和星期內,代表沒有特定的值。如果使用*號日期了星期會有歧義,這是使用?
L 只能出現在日期和星期內,表示月的最後一天,或者星期六
W 只能出現在日期內,表示最接近這個日期的工作日
㈢ java quartz 定時任務,每次執行都有多個線程同時執行
解決了就好,Java中定時任務也可以用timer
㈣ 如何監控java quartz定時器中的所有定時任務
眾所周知spring 的Quartz定時器的功能非常強大,可以在特定的年月日小時分秒的時間點觸發時間,完成事件的調度,就像windows中得計劃任務一樣。下面看一個典型的Quartz定時器的實現:
1、首先實現一個用於被執行的類,這個類用於被定時器調度,這個類不需要繼承任何類或者介面,代碼如下:
publicTestQuartz{
public void doSomething(){ //TODO } }
2、spring配置文件,具體配置
<!-- 被執行類 -->
<beanid="testQuarzt"class="test.testQuarzt"/>
<!-- 將testQuarzt注入到job中 -->
<beanid="testQuartzJob"class="org.springframework.scheling.quartz.">
<property name="targetObject" ref="testQuarzt" /> <property name="targetMethod" value="doSomething" /> <property name="concurrent" value="false" /> </bean>
<!-- 將job注入到定時觸發器 -->
<beanid="testTrigger"class="org.springframework.scheling.quartz.CronTriggerBean"> <property name="jobDetail" ref="testQuartzJob" /> <property name="cronExpression"> <value>0 0 6 * * ?<value> <property> <bean>
<!-- 將定時觸發器注入任務工程 -->
<beanclass="org.springframework.scheling.quartz.SchelerFactoryBean"> <property name="triggers"> <list>
㈤ org.quartz.scheler對過時任務是怎麼處理,配置文件scheler.properties中
問的是java quartz的配置吧
在並發任務下,每個任務啟用一個線程,如果線程池中的線程已經用完,再來任務時需要等待,直到有線程可用。如果等待時間過長,超過了org.quartz.jobStore.misfireThreshold設置的時間,本次任務不再執行。直到有任務執行完空出線程池,以此時間為基準開始下次任務執行。
misfireThreshold只有當job任務被阻塞時才有效,如果線程池裡線程很多,該參數沒有意義,所以大部分時候只對有狀態的job才有意義。
參考:http://www.cnblogs.com/abinxm/archive/2011/09/29/2195944.html
㈥ java下quartz 怎麼設置單線程執行
如果你是直接寫的代碼設置時間的,可以設置每48小時,翻翻API就有了,既然你問了,肯定是通過XML配置文件寫的,那隻能給一個解決方案了,在配置文件中雖然有0 0 0 1/2 * ? 來表示從每月1號起每2天0點0分0秒執行一次,但遇到31這樣的月份就會錯,不建議使用。
想到的解決方案有2種,一種設置成每天跑一次,定義個static boolean變數 第一次執行的時候改成false並執行,第2天的執行獲取該值,發現是false把值變成true不執行,發現是true改成false執行。
第2種方法其實是為了防止項目被重啟static變數重置的,這個boolean值(或者你自定義的標示符)放到資料庫里,沒天執行的時候讀一下庫。當然在指定位置生成一個空文件,每次執行判斷該位置的文件是否存在也一樣(覆蓋項目的時候記得,如果這個文件有復制到相關位置就好了)
㈦ java quartz job 執行時間配置
第一步:引包
要使用Quartz,必須要引入以下這幾個包:
1、log4j-1.2.16
2、quartz-2.1.7
3、slf4j-api-1.6.1.jar
4、slf4j-log4j12-1.6.1.jar
這些包都在下載的Quartz包裡麵包含著,因此沒有必要為尋找這幾個包而頭疼。
第二步:創建要被定執行的任務類
這一步也很簡單,只需要創建一個實現了org.quartz.Job介面的類,並實現這個介面的唯一一個方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class myJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(sdf.format(new Date()));
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class myJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(sdf.format(new Date()));
}
}
這個例子很簡單,就不用解說了。
第三步:創建任務調度,並執行
這一步應該算是最難的一步的,但其實是非常簡單的,直接上代碼
import static org.quartz.CronScheleBuilder.cronSchele;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheler;
import org.quartz.SchelerFactory;
import org.quartz.impl.StdSchelerFactory;
public class Test {
public void go() throws Exception {
// 首先,必需要取得一個Scheler的引用
SchelerFactory sf = new StdSchelerFactory();
Scheler sched = sf.getScheler();
//jobs可以在scheled的sched.start()方法前被調用
//job 1將每隔20秒執行一次
JobDetail job = newJob(myJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchele(cronSchele("0/20 * * * * ?")).build();
Date ft = sched.scheleJob(job, trigger);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(job.getKey() + " 已被安排執行於: " + sdf.format(ft) + ",並且以如下重復規則重復執行: " + trigger.getCronExpression());
// job 2將每2分鍾執行一次(在該分鍾的第15秒)
job = newJob(myJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchele(cronSchele("15 0/2 * * * ?")).build();
ft = sched.scheleJob(job, trigger);
System.out.println(job.getKey() + " 已被安排執行於: " + sdf.format(ft) + ",並且以如下重復規則重復執行: "+ trigger.getCronExpression());
// 開始執行,start()方法被調用後,計時器就開始工作,計時調度中允許放入N個Job
sched.start();
try {
//主線程等待一分鍾
Thread.sleep(60L * 1000L);
} catch (Exception e) {}
//關閉定時調度,定時器不再工作
sched.shutdown(true);
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.go();
}
}
import static org.quartz.CronScheleBuilder.cronSchele;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheler;
import org.quartz.SchelerFactory;
import org.quartz.impl.StdSchelerFactory;
public class Test {
public void go() throws Exception {
// 首先,必需要取得一個Scheler的引用
SchelerFactory sf = new StdSchelerFactory();
Scheler sched = sf.getScheler();
//jobs可以在scheled的sched.start()方法前被調用
//job 1將每隔20秒執行一次
JobDetail job = newJob(myJob.class).withIdentity("job1", "group1").build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchele(cronSchele("0/20 * * * * ?")).build();
Date ft = sched.scheleJob(job, trigger);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(job.getKey() + " 已被安排執行於: " + sdf.format(ft) + ",並且以如下重復規則重復執行: " + trigger.getCronExpression());
// job 2將每2分鍾執行一次(在該分鍾的第15秒)
job = newJob(myJob.class).withIdentity("job2", "group1").build();
trigger = newTrigger().withIdentity("trigger2", "group1").withSchele(cronSchele("15 0/2 * * * ?")).build();
ft = sched.scheleJob(job, trigger);
System.out.println(job.getKey() + " 已被安排執行於: " + sdf.format(ft) + ",並且以如下重復規則重復執行: "+ trigger.getCronExpression());
// 開始執行,start()方法被調用後,計時器就開始工作,計時調度中允許放入N個Job
sched.start();
try {
//主線程等待一分鍾
Thread.sleep(60L * 1000L);
} catch (Exception e) {}
//關閉定時調度,定時器不再工作
sched.shutdown(true);
}
public static void main(String[] args) throws Exception {
Test test = new Test();
test.go();
}
}
OK了,Job1和Job2就會被安排為定時執行了。此時程序是可以執行的了,但是可能會輸出WARN級別日誌,這是因為沒有加log4j的配置文件,加上配置文件,就OK了。這里需要說明的地方只有一個,其它的可以直接Copy到您的項目裡面。看代碼:
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchele(cronSchele("0/20 * * * * ?")).build();
CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchele(cronSchele("0/20 * * * * ?")).build();
㈧ java quartz 如何配置, 兩天執行一次,且0點執行
如果你是直接寫的代碼設置時間的,可以設置每48小時,翻翻API就有了,既然你問了,肯定是通過XML配置文件寫的,那隻能給一個解決方案了,在配置文件中雖然有0 0 0 1/2 * ? 來表示從每月1號起每2天0點0分0秒執行一次,但遇到31這樣的月份就會錯,不建議使用。
想到的解決方案有2種,一種設置成每天跑一次,定義個static boolean變數 第一次執行的時候改成false並執行,第2天的執行獲取該值,發現是false把值變成true不執行,發現是true改成false執行。
第2種方法其實是為了防止項目被重啟static變數重置的,這個boolean值(或者你自定義的標示符)放到資料庫里,沒天執行的時候讀一下庫。當然在指定位置生成一個空文件,每次執行判斷該位置的文件是否存在也一樣(覆蓋項目的時候記得,如果這個文件有復制到相關位置就好了)