日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java实现定时调度的三种方法

發布時間:2025/4/16 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java实现定时调度的三种方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、Timer

Timer myTimer = new Timer(); ?

? ? ? ? myTimer.schedule(new Worker(), 1000);//1秒后執行 ?
// ? ? ?2012-02-28 09:58:00執行 ?
? ? ? ? myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00")); ?
? ? ? ? myTimer.schedule(new Worker(), 5000,1000);//5秒后執行 每一秒執行一次 ?
// ? ? ?2012-02-28 09:58:00執行一次 以后每秒執行一次,如果設定的時間點在當前時間之前,任務會被馬上執行,然后開始按照設定的周期定時執行任務 ?
? ? ? ? myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000); ?
? ? ? ? myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后執行 每一秒執行一次 如果該任務因為某些原因(例如垃圾收集)而延遲執行,那么接下來的任務會盡可能的快速執行,以趕上特定的時間點 ?
? ? ? ? myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上個類似 ?

timer的缺點:

(1)Timer對調度的支持是基于絕對時間,而不是相對時間的,由此任務對系統時鐘的改變是敏感的;

(2)所有的TimerTask只有一個線程TimerThread來執行,因此同一時刻只有一個TimerTask在執行;

(3)Timer線程并不捕獲異常,所以任何一個TimerTask的執行異常都會導致Timer終止所有任務;這種情況下,Timer也不會再重新恢復線程的執行了;它錯誤的認為整個Timer都被取消了。此時,已經被安排但尚未執行的TimerTask永遠不會再執行了,新的任務也不能被調度了。


因此你應該考慮使用ScheduledThreadPoolExecutor作為代替品,ScheduledThreadExecutor只支持相對時間。

2、ScheduleExecutorService


ScheduleExecutorService接口中有四個重要的方法,其中scheduleAtFixedRate和scheduleWithFixedDelay在實現定時程序時比較方便。



(1)scheduleAtFixedRate


public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, ?
? ? ? ? ? ? long initialDelay, ?
? ? ? ? ? ? long period, ?
? ? ? ? ? ? TimeUnit unit); ?
command:執行線程
initialDelay:初始化延時
period:兩次開始執行最小間隔時間

unit:計時單位


(2)scheduleWithFixedDelay

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, ?

? ? ? ? ? ? ? ? long initialDelay, ?
? ? ? ? ? ? ? ? long delay, ?
? ? ? ? ? ? ? ? TimeUnit unit); ?
command:執行線程
initialDelay:初始化延時
period:前一次執行結束到下一次執行開始的間隔時間(間隔執行延遲時間)
unit:計時單位


(3)功能示例

1.按指定頻率周期執行某個任務。
初始化延遲0ms開始執行,每隔100ms重新執行一次任務。

/**?
?* 以固定周期頻率執行任務?
?*/ ?
public static void executeFixedRate() { ?
? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); ?
? ? executor.scheduleAtFixedRate( ?
? ? ? ? ? ? new EchoServer(), ?
? ? ? ? ? ? 0, ?
? ? ? ? ? ? 100, ?
? ? ? ? ? ? TimeUnit.MILLISECONDS); ?
} ?

間隔指的是連續兩次任務開始執行的間隔。

對于scheduleAtFixedRate方法,當執行任務的時間大于我們指定的間隔時間時,它并不會在指定間隔時開辟一個新的線程并發執行這個任務。而是等待該線程執行完畢。

2.按指定頻率間隔執行某個任務。
初始化時延時0ms開始執行,本次執行結束后延遲100ms開始下次執行。

/**?
?* 以固定延遲時間進行執行?
?* 本次任務執行完成后,需要延遲設定的延遲時間,才會執行新的任務?
?*/ ?
public static void executeFixedDelay() { ?
? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); ?
? ? executor.scheduleWithFixedDelay( ?
? ? ? ? ? ? new EchoServer(), ?
? ? ? ? ? ? 0, ?
? ? ? ? ? ? 100, ?
? ? ? ? ? ? TimeUnit.MILLISECONDS); ?

} ?

間隔指的是連續上次執行完成和下次開始執行之間的間隔。


3.周期定時執行某個任務。


有時候我們希望一個任務被安排在凌晨3點(訪問較少時)周期性的執行一個比較耗費資源的任務,可以使用下面方法設定每天在固定時間執行一次任務。

/**?
?* 每天晚上8點執行一次?
?* 每天定時安排任務進行執行?
?*/ ?
public static void executeEightAtNightPerDay() { ?
? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); ?
? ? long oneDay = 24 * 60 * 60 * 1000; ?
? ? long initDelay ?= getTimeMillis("20:00:00") - System.currentTimeMillis(); ?
? ? initDelay = initDelay > 0 ? initDelay : oneDay + initDelay; ?
??
? ? executor.scheduleAtFixedRate( ?
? ? ? ? ? ? new EchoServer(), ?
? ? ? ? ? ? initDelay, ?
? ? ? ? ? ? oneDay, ?
? ? ? ? ? ? TimeUnit.MILLISECONDS); ?
} ?

/**?
?* 獲取指定時間對應的毫秒數?
?* @param time "HH:mm:ss"?
?* @return?
?*/ ?
private static long getTimeMillis(String time) { ?
? ? try { ?
? ? ? ? DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); ?
? ? ? ? DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd"); ?
? ? ? ? Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time); ?
? ? ? ? return curDate.getTime(); ?
? ? } catch (ParseException e) { ?
? ? ? ? e.printStackTrace(); ?
? ? } ?
? ? return 0; ?
} ?


3、Spring


除了我們自己實現定時任務之外,我們可以使用Spring幫我們完成這樣的事情。
Spring自動定時任務配置方法(我們要執行任務的類名為com.study.MyTimedTask)

<bean id="myTimedTask" class="com.study.MyTimedTask"/> ?



<bean id="doMyTimedTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> ?
? ? <property name="targetObject" ref="myTimedTask"/> ?
? ? <property name="targetMethod" value="execute"/> ?
? ? <property name="concurrent" value="false"/> ?
</bean> ?



<bean id="myTimedTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> ?
? ? <property name="jobDetail" ref="doMyTimedTask"/> ?
? ? <property name="cronExpression" value="0 0 2 * ?"/> ?
</bean> ?


<bean id="doScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> ?
? ? <property name="triggers"> ?
? ? ? ? <list> ?
? ? ? ? ? ? <ref local="myTimedTaskTrigger"/> ?
? ? ? ? </list> ?
? ? </property> ?
</bean> ?



<bean id="doScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> ?
? ? <property name="triggers"> ?
? ? ? ? <list> ?
? ? ? ? ? ? <bean class="org.springframework.scheduling.quartz.CronTriggerBean"> ?
? ? ? ? ? ? ? ? <property name="jobDetail"/> ?
? ? ? ? ? ? ? ? ? ? <bean id="doMyTimedTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> ?
? ? ? ? ? ? ? ? ? ? ? ? <property name="targetObject"> ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? <bean class="com.study.MyTimedTask"/> ?
? ? ? ? ? ? ? ? ? ? ? ? </property> ?
? ? ? ? ? ? ? ? ? ? ? ? <property name="targetMethod" value="execute"/> ?
? ? ? ? ? ? ? ? ? ? ? ? <property name="concurrent" value="false"/> ?
? ? ? ? ? ? ? ? ? ? </bean> ?
? ? ? ? ? ? ? ? </property> ?
? ? ? ? ? ? ? ? <property name="cronExpression" value="0 0 2 * ?"/> ?
? ? ? ? ? ? </bean> ?
? ? ? ? </list> ?
? ? </property> ?
</bean> ?

總結

以上是生活随笔為你收集整理的Java实现定时调度的三种方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。