① java中如何使用任務調度
資料庫:使用觸發器存儲過程 java:
1.JDK自帶的 Timer計時器 | TimerTask任務對象 本篇博客詳細說下這個方法
2 spring提供的quartz子框架
② 為什麼使用java 任務調度系統
Timer
相信大家都已經非常熟悉 java.util.Timer 了,它是最簡單的一種實現任務調度的方法,下面給出一個具體的例子:
清單 1. 使用 Timer 進行任務調度
package com.ibm.scheler;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest extends TimerTask {
private String jobName = "";
public TimerTest(String jobName) {
super();
this.jobName = jobName;
}
@Override
public void run() {
System.out.println("execute " + jobName);
}
public static void main(String[] args) {
Timer timer = new Timer();
long delay1 = 1 * 1000;
long period1 = 1000;
// 從現在開始 1 秒鍾之後,每隔 1 秒鍾執行一次 job1
timer.schele(new TimerTest("job1"), delay1, period1);
long delay2 = 2 * 1000;
long period2 = 2000;
// 從現在開始 2 秒鍾之後,每隔 2 秒鍾執行一次 job2
timer.schele(new TimerTest("job2"), delay2, period2);
}
}
Output:
execute job1
execute job1
execute job2
execute job1
execute job1
execute job2
使用 Timer 實現任務調度的核心類是 Timer 和 TimerTask。其中 Timer 負責設定 TimerTask 的起始與間隔執行時間。使用者只需要創建一個 TimerTask 的繼承類,實現自己的 run 方法,然後將其丟給 Timer 去執行即可。
Timer 的設計核心是一個 TaskList 和一個 TaskThread。Timer 將接收到的任務丟到自己的 TaskList 中,TaskList 按照 Task 的最初執行時間進行排序。TimerThread 在創建 Timer 時會啟動成為一個守護線程。這個線程會輪詢所有任務,找到一個最近要執行的任務,然後休眠,當到達最近要執行任務的開始時間點,TimerThread 被喚醒並執行該任務。之後 TimerThread 更新最近一個要執行的任務,繼續休眠。
Timer 的優點在於簡單易用,但由於所有任務都是由同一個線程來調度,因此所有任務都是串列執行的,同一時間只能有一個任務在執行,前一個任務的延遲或異常都將會影響到之後的任務。
回頁首
ScheledExecutor
鑒於 Timer 的上述缺陷,Java 5 推出了基於線程池設計的 ScheledExecutor。其設計思想是,每一個被調度的任務都會由線程池中一個線程去執行,因此任務是並發執行的,相互之間不會受到干擾。需要注意的是,只有當任務的執行時間到來時,ScheedExecutor 才會真正啟動一個線程,其餘時間 ScheledExecutor 都是在輪詢任務的狀態。
清單 2. 使用 ScheledExecutor 進行任務調度
package com.ibm.scheler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheledExecutorTest implements Runnable {
private String jobName = "";
public ScheledExecutorTest(String jobName) {
super();
this.jobName = jobName;
}
@Override
public void run() {
System.out.println("execute " + jobName);
}
public static void main(String[] args) {
ScheledExecutorService service = Executors.newScheledThreadPool(10);
long initialDelay1 = 1;
long period1 = 1;
// 從現在開始1秒鍾之後,每隔1秒鍾執行一次job1
service.scheleAtFixedRate(
new ScheledExecutorTest("job1"), initialDelay1,
period1, TimeUnit.SECONDS);
long initialDelay2 = 1;
long delay2 = 1;
// 從現在開始2秒鍾之後,每隔2秒鍾執行一次job2
service.scheleWithFixedDelay(
new ScheledExecutorTest("job2"), initialDelay2,
delay2, TimeUnit.SECONDS);
}
}
Output:
execute job1
execute job1
execute job2
execute job1
execute job1
execute job2
清單 2 展示了 ScheledExecutorService 中兩種最常用的調度方法 ScheleAtFixedRate 和 ScheleWithFixedDelay。ScheleAtFixedRate 每次執行時間為上一次任務開始起向後推一個時間間隔,即每次執行時間為 :initialDelay, initialDelay+period, initialDelay+2*period, …;ScheleWithFixedDelay 每次執行時間為上一次任務結束起向後推一個時間間隔,即每次執行時間為:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。由此可見,ScheleAtFixedRate 是基於固定時間間隔進行任務調度,ScheleWithFixedDelay 取決於每次任務執行的時間長短,是基於不固定時間間隔進行任務調度。
回頁首
用 ScheledExecutor 和 Calendar 實現復雜任務調度
Timer 和 ScheledExecutor 都僅能提供基於開始時間與重復間隔的任務調度,不能勝任更加復雜的調度需求。比如,設置每星期二的 16:38:10 執行任務。該功能使用 Timer 和 ScheledExecutor 都不能直接實現,但我們可以藉助 Calendar 間接實現該功能。
清單 3. 使用 ScheledExcetuor 和 Calendar 進行任務調度
package com.ibm.scheler;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheledExceutorTest2 extends TimerTask {
private String jobName = "";
public ScheledExceutorTest2(String jobName) {
super();
this.jobName = jobName;
}
@Override
public void run() {
System.out.println("Date = "+new Date()+", execute " + jobName);
}
/**
* 計算從當前時間currentDate開始,滿足條件dayOfWeek, hourOfDay,
* minuteOfHour, secondOfMinite的最近時間
* @return
*/
public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek,
int hourOfDay, int minuteOfHour, int secondOfMinite) {
//計算當前時間的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各個欄位值
int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR);
int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);
int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);
int currentMinute = currentDate.get(Calendar.MINUTE);
int currentSecond = currentDate.get(Calendar.SECOND);
//如果輸入條件中的dayOfWeek小於當前日期的dayOfWeek,則WEEK_OF_YEAR需要推遲一周
boolean weekLater = false;
if (dayOfWeek < currentDayOfWeek) {
weekLater = true;
} else if (dayOfWeek == currentDayOfWeek) {
//當輸入條件與當前日期的dayOfWeek相等時,如果輸入條件中的
//hourOfDay小於當前日期的
//currentHour,則WEEK_OF_YEAR需要推遲一周
if (hourOfDay < currentHour) {
weekLater = true;
} else if (hourOfDay == currentHour) {
//當輸入條件與當前日期的dayOfWeek, hourOfDay相等時,
//如果輸入條件中的minuteOfHour小於當前日期的
//currentMinute,則WEEK_OF_YEAR需要推遲一周
if (minuteOfHour < currentMinute) {
weekLater = true;
} else if (minuteOfHour == currentSecond) {
//當輸入條件與當前日期的dayOfWeek, hourOfDay,
//minuteOfHour相等時,如果輸入條件中的
//secondOfMinite小於當前日期的currentSecond,
//則WEEK_OF_YEAR需要推遲一周
if (secondOfMinite < currentSecond) {
weekLater = true;
}
}
}
}
if (weekLater) {
//設置當前日期中的WEEK_OF_YEAR為當前周推遲一周
currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1);
}
// 設置當前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND為輸入條件中的值。
currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek);
currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
currentDate.set(Calendar.MINUTE, minuteOfHour);
currentDate.set(Calendar.SECOND, secondOfMinite);
return currentDate;
}
public static void main(String[] args) throws Exception {
ScheledExceutorTest2 test = new ScheledExceutorTest2("job1");
//獲取當前時間
Calendar currentDate = Calendar.getInstance();
long currentDateLong = currentDate.getTime().getTime();
System.out.println("Current Date = " + currentDate.getTime().toString());
//計算滿足條件的最近一次執行時間
Calendar earliestDate = test
.getEarliestDate(currentDate, 3, 16, 38, 10);
long earliestDateLong = earliestDate.getTime().getTime();
System.out.println("Earliest Date = "
+ earliestDate.getTime().toString());
//計算從當前時間到最近一次執行時間的時間間隔
long delay = earliestDateLong - currentDateLong;
//計算執行周期為一星期
long period = 7 * 24 * 60 * 60 * 1000;
ScheledExecutorService service = Executors.newScheledThreadPool(10);
//從現在開始delay毫秒之後,每隔一星期執行一次job1
service.scheleAtFixedRate(test, delay, period,
TimeUnit.MILLISECONDS);
}
}
Output:
Current Date = Wed Feb 02 17:32:01 CST 2011
Earliest Date = Tue Feb 8 16:38:10 CST 2011
Date = Tue Feb 8 16:38:10 CST 2011, execute job1
Date = Tue Feb 15 16:38:10 CST 2011, execute job1
③ java任務調度表達式
最最最笨的辦法,只用JAVA寫的話,看你自己定義,每1小時將循環執行一次,循環一次最前獲取當前時間的HH,也就是小時,判斷是否是02,如果是,調用自己程序...最好寫個線程來調用,別搞成死循環的離譜,把內存都吃光光了:)
④ java多實例下任務調度問題
有個比較簡單的方法,
那就是首先在資料庫中加入一個表,用來專門保存任務的。
在應用啟動任務時,根據任務ID,去select * from taskID=*** for update
利用 for update的特性實現一個鎖機制(如果獲取數據成功就執行任務,如果失敗就退出)。
在任務完成後再釋放。
⑤ JavaWeb應用中如何實現任務有效調度
任務調度是大型J2EEweb應用中常見的工作。開發者希望以指定的間隔時間執行各類操作,並完成一些無需用戶輸入的任務。java中可有無數方法來做到這一點,但是在web應用中卻並沒有這方面的統一標准。當許多開發人員參與同一個項目,並且以各自不同的方式來實現任務調度時,就可能產生很大問題。內存和同步問題就是必須首先考慮的兩件事。事實上,一些開發者試圖調用操作系統層面的任務調度機制,如Unix平台上的cron。這種編程實踐也許並不是太壞,但它將直接導致可移植性被拋到九霄雲外。
⑥ java任務調度 雙機熱備
可以通過一個資料庫的table去設定達到你想要的結果。每次執行更新這個table的執行時間和執行的伺服器,如果監測到一個伺服器三分鍾都沒有執行,就可以啟動備用機。
⑦ 幾種任務調度的 Java 實現方法與比較
<!-- 要調用的工作類 -->
<bean id="quartzJob" class="com.quartz.QuartzJob"></bean>
<!-- 定義調用對象和調用對象的方法 -->
<bean id="jobtask" class="org.springframework.scheling.quartz.">
<!-- 調用的類 -->
<property name="targetObject">
<ref bean="quartzJob"/>
</property>
<!-- 調用類中的方法 -->
<property name="targetMethod">
<value>work</value>
</property>
</bean>
<!-- 定義觸發時間 -->
<bean id="doTime" class="org.springframework.scheling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="jobtask"/>
</property>
<!-- cron表達式 -->
<property name="cronExpression">
<value>0 0/2 * * * ?</value>
</property>
</bean>
⑧ java如何延時調用web service
延時調用?是指睡眠一定時間在調用ws還是定時調用ws?
如果單純的希望運行某方法一定時間後在調用ws可以使用Thread.sleep
如果是輪詢,每隔一段時間調用ws可以使用以下幾種:
1. spring框架整合的Quartz;
2. 使用ScheledThreadPoolExecutor 調度定時任務;
3. 使用Timer 調度定時任務;
你可以先學習學習timer
⑨ Java Web應用中如何實現任務有效調度
任務調度是大型J2EEweb應用中常見的工作。開發者希望以指定的間隔時間執行各類操作,並完成一些無需用戶輸入的任務。java中可有無數方法來做到這一點,但是在web應用中卻並沒有這方面的統一標准。當許多開發人員參與同一個項目,並且以各自不同的方式來實現任務調度時,就可能產生很大問題。內存和同步問題就是必須首先考慮的兩件事。事實上,一些開發者試圖調用操作系統層面的任務調度機制,如Unix平台上的cron。這種編程實踐也許並不是太壞,但它將直接導致可移植性被拋到九霄雲外。