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方法,當執行任務的時間大於我們指定的間隔時間時,它並不會在指定間隔時開闢一個新的執行緒併發執行這個任務。而是等待該執行緒執行完畢。
初始化時延時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實現定時排程的三種方法
1、Timer Timer myTimer = new Timer(); myTimer.schedule(new Worker(), 1000);//1秒後執行 // 2012-02-28 09:58:00執行 myT
一、多執行緒基礎概念、實現執行緒三種方法、中斷執行緒方法,以及執行緒狀態轉化
1、CPU核心數和執行緒數的關係 1:1的關係,引入超執行緒之後,就是1:2 2、cpu時間輪轉機制,即RR排程 3、程序和執行緒 程序:程式執行資源分配最小單位,程序內部有多個執行緒,多個執行緒之間會共享程序資源 執行緒:CPU排程的最小單位 4、並行和併發
前端實現三角形的三種方法
直接貼程式碼行不行?我是個不善於表達的姑娘QAQ 第一種 HTML+CSS <div class="box"></div> <style> .box{
Java實現克隆的三種方式
1. 淺克隆 2. 深克隆 3. 利用序列化實現深克隆 1、淺複製(淺克隆)這種淺複製,其實也就是把被複制的這個物件的一些變數值拿過來了。最後生成student2還是一個新的物件。 public class
單鏈表實現反轉的三種方法
單鏈表的操作是面試中經常會遇到的問題,今天總結一下反轉的幾種方案: 1 ,兩兩對換 2, 放入陣列,倒置陣列 3, 遞迴實現 程式碼如下: #include<stdio.h> #include<malloc.h> typ
JAVA寫JSON的三種方法,java物件轉json資料
今天給大家講一個物件、物件集合轉json資料的三種方法,三種方法最終達到的效果是一樣的。jsonlib:個人感覺最麻煩的一個需要匯入的包也多,程式碼也相對多一些。Gson:google的。FastJson:阿里巴巴的,個人覺得這個比較好,而且據說這個也是效能最好一個。下面就貼
java實現克隆的三種(很最全面)
1、淺複製(淺克隆)這種淺複製,其實也就是把被複制的這個物件的一些變數值拿過來了。最後生成student2還是一個新的物件。public class CloneTest1 { public static void main(String[] args) throws Exc
Java實現websocket 的兩種方法
一.WebSocket簡單介紹 隨著網際網路的發展,傳統的HTTP協議已經很難滿足Web應用日益複雜的需求了。近年來,隨著HTML5的誕生,WebSocket協議被提出,它實現了瀏覽器與伺服器的全雙工通訊,擴充套件了瀏覽器與服務端的通訊功能,使服務端也能主動向客戶端傳送資料。 我們知道,傳統的HTTP協議
java 字串擷取的三種方法 推薦
1.split()+正則表示式來進行擷取。 將正則傳入split()。返回的是一個字串陣列型別
Java字串分割的三種方法
一、StringTokenizer方法 Java中substring方法可以分解字串,返回的是原字串的一個子字串。如果要講一個字串分解為一個一個的單詞或者標記,StringTokenizer可
java時間格式化的三種方法
使用fmt函式需在jsp中引入 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><fmt:formatDate value="${item.expDate}" pattern="yyyy-MM-dd"/>
實現servlet介面三種方法的區別
首先明確,Servlet並不是專門用於處理Http請求的。然後再說三種方式的聯絡和區別。1)原生Servlet介面package javax.servlet; import java.io.IOException; public interface Servlet { public void
RecyclerView實現addHeadView的三種方法原理說明和利弊分析(footHead同理)
介紹 上一篇部落格我分析了ListView的原始碼看Google是怎麼樣實現addHeadView的,原始碼的思路是對繫結在ListView的Adapter做轉換,在我們呼叫addHeadView的時候把已經寫好的BaseAdapter轉換成HeaderVie
java 載入類的三種方法
載入類的幾種方法 所有資源都通過ClassLoader載入到JVM裡,那麼在載入資源時當然可以使用ClassLoader,只是對於不同的資源還可以使用一些別的方式載入,例如對於類可以直接new,對於
java 字串擷取的三種方法(推薦)
1.split()+正則表示式來進行擷取。 將正則傳入split()。返回的是一個字串陣列型別。不過通過這種方式擷取會有很大的效能損耗,因為分析正則非常耗時。 String str = "abc,12,3yy98,0"; String[] strs=str.split(
Java JDBC 連線 Oracle 三種方法
Java JDBC 連線 Oracle 三種方法 Oracle JDBC 連線ServiceName jdbc:oracle:thin:@//:/ 例:jdbc:oracle:[email protected]//10.1.112.110:1521/H
【c++】模擬實現迴圈佇列 三種方法(標識、浪費一個空間、計數器)
什麼是迴圈佇列? 為充分利用向量空間,克服”假溢位“現象的方法:將向量空間想象為一個首尾相接的圓環,並稱這種向量為迴圈向量。儲存在其中的佇列稱為迴圈佇列(Circular Queue)。 假象成如圖: 但實際上儲存空間還是一段連續的空間。 空佇列: 當有元素入隊時:
java實現定時任務的三種方法
/** * 普通thread * 這是最常見的,建立一個thread,然後讓它在while迴圈裡一直執行著, * 通過sleep方法來達到定時任務的效果。這樣可以快速簡單的實現,程式碼如下: * @author GT * */ public class Task
java實現斐波那契數列的三種方法
Java實現斐波那契數列的三種方法 什麼是斐波那契數列 這裡借用一下度孃的一段話:斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是
Java——實現Java多執行緒的三種方法
Java虛擬機器允許應用程式併發地執行多個執行緒。在Java語言中,多執行緒的實現一般有以下3種方法,其中前兩種是最常用的方法。 1.繼承Thread類,重寫run()方法 Thread本質上也是實現了Runnable介面的一個例項,它代表一個執行緒的例項。並且,啟動執行緒的唯一方法就是通過