Java實現(xiàn)定時任務(wù)_第1頁
Java實現(xiàn)定時任務(wù)_第2頁
Java實現(xiàn)定時任務(wù)_第3頁
Java實現(xiàn)定時任務(wù)_第4頁
Java實現(xiàn)定時任務(wù)_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第Java實現(xiàn)定時任務(wù)本文實例為大家分享了Java實現(xiàn)定時任務(wù)的具體代碼,供大家參考,具體內(nèi)容如下

1使用java.util.Timer

這種方式的定時任務(wù)主要用到兩個類,Timer和TimerTask,使用起來比較簡單。其中Timer負責(zé)設(shè)定TimerTask的起始與間隔執(zhí)行時間。TimerTask是一個抽象類,new的時候?qū)崿F(xiàn)自己的run方法,然后將其丟給Timer去執(zhí)行即可。

代碼示例:

importjava.time.LocalDateTime;

importjava.util.Timer;

importjava.util.TimerTask;

publicclassSchedule{

publicstaticvoidmain(String[]args){

TimerTasktimerTask=newTimerTask(){

@Override

publicvoidrun(){

System.out.println("當前線程:"+Thread.currentThread().getName()+"當前時間"+LocalDateTime.now());

}

};

//在指定延遲0毫秒后開始,隨后地執(zhí)行以2000毫秒間隔執(zhí)行timerTask

newTimer().schedule(timerTask,0L,2000L);

System.out.println("當前線程:"+Thread.currentThread().getName()+"當前時間"+LocalDateTime.now());

}

}

缺點:

Timer的背后只有一個線程,不管有多少個任務(wù),都只有一個工作線程串行執(zhí)行,效率低下受限于單線程,如果第一個任務(wù)邏輯上死循環(huán)了,后續(xù)的任務(wù)一個都得不到執(zhí)行依然是由于單線程,任一任務(wù)拋出異常后,整個Timer就會結(jié)束,后續(xù)任務(wù)全部都無法執(zhí)行

2使用ScheduledExecutorService

ScheduledExecutorService即是Timer的替代者,JDK1.5并發(fā)包引入,是基于線程池設(shè)計的定時任務(wù)類。每個調(diào)度任務(wù)都會分配到線程池中的某一個線程去執(zhí)行,任務(wù)就是并發(fā)調(diào)度執(zhí)行的,任務(wù)之間互不影響。

Java5.0引入了java.util.concurrent包,其中的并發(fā)實用程序之一是ScheduledThreadPoolExecutor,它是一個線程池,用于以給定的速率或延遲重復(fù)執(zhí)行任務(wù)。它實際上是Timer/TimerTask組合的更通用替代品,因為它允許多個服務(wù)線程,接受各種時間單位,并且不需要子類TimerTask(只需實現(xiàn)Runnable)。使用一個線程配置ScheduledThreadPoolExecutor使其等效于Timer。

代碼示例:

importjava.time.LocalDateTime;

importjava.util.concurrent.*;

publicclassSchedule{

publicstaticvoidmain(String[]args){

//創(chuàng)建一個ScheduledThreadPoolExecutor線程池,核心線程數(shù)為5

ScheduledExecutorServicescheduledExecutorService=newScheduledThreadPoolExecutor(5);

//創(chuàng)建Runnable打印當前線程和當前時間

Runnabler=()-System.out.println("當前線程:"+Thread.currentThread().getName()+"當前時間"+LocalDateTime.now());

/**

*schedule:只執(zhí)行一次調(diào)度

*scheduleAtFixedRate:一開始就計算間隔時間,如果任務(wù)超過間隔時間,那么就直接開始下一個任務(wù)

*scheduleWithFixedDelay:任務(wù)無論執(zhí)行多久,都要等待上一輪任務(wù)完成之后再間隔指定時間,然后才開始下一個任務(wù)

*/

//在指定1秒延遲后執(zhí)行r,之后每兩秒執(zhí)行一次

scheduledExecutorService.scheduleAtFixedRate(r,1,2,TimeUnit.SECONDS);

}

}

3使用SpringTask

SpringTask底層是基于JDK的ScheduledThreadPoolExecutor線程池來實現(xiàn)的。直接通過Spring提供的@Scheduled注解即可定義定時任務(wù),非常方便。

以SpringBoot來作為示例,步驟為

1.在啟動類所在包下創(chuàng)建Schedule類(在沒有配置@ComponentScan的情況下,SpringBoot只會默認掃描啟動類所在包的spring組件)

2.在該類上添加@Component和@EnableScheduling注解

3.在方法上添加@Scheduled注解,該注解主要參數(shù)如下

Stringcron()default"";

//支持cron表達式

longfixedDelay()default-1;

//在最后一次調(diào)用結(jié)束和下一次調(diào)用開始之間的時間間隔,以毫秒為單位

StringfixedDelayString()default"";

//同上,類似ScheduledExecutorService的scheduleWithFixedDelay

longfixedRate()default-1;

//在調(diào)用之前的時間間隔,以毫秒為單位

StringfixedRateString()default"";

//同上,類似ScheduledExecutorService的scheduleAtFixedRate

longinitialDelay()default-1;

//在第一次執(zhí)行fixedRate()或fixedDelay()任務(wù)之前要延遲的毫秒數(shù)

StringinitialDelayString()default"";

//同上

代碼示例:

importorg.springframework.scheduling.annotation.EnableScheduling;

importorg.springframework.scheduling.annotation.Scheduled;

importorg.springframework.stereotype.Component;

importjava.time.LocalDateTime;

@Component

@EnableScheduling

publicclassSchedule{

@Scheduled(fixedRate=2000L)

publicvoidtask(){

System.out.println("當前線程:"+Thread.currentThread().getName()+"當前時間"+LocalDateTime.now());

}

}

優(yōu)點:簡單,輕量,支持Cron表達式缺點:默認只支持單機,是單線程的,并且提供的功能比較單一

可以通過@EnableAsync和@Async開啟多線程

importorg.springframework.scheduling.annotation.Async;

importorg.springframework.scheduling.annotation.EnableAsync;

importorg.springframework.scheduling.annotation.EnableScheduling;

importorg.springframework.scheduling.annotation.Scheduled;

importorg.springframework.stereotype.Component;

importjava.time.LocalDateTime;

@Component

@EnableAsync

//開啟異步多線程

@EnableScheduling

publicclassSchedule{

@Async

@Scheduled(fixedRate=2000L)

publicvoidtask(){

System.out.println("當前線程:"+Thread.currentThread().getName()+"當前時間"+LocalDateTime.now());

}

}

使用@EnableAsync注解后,默認情況下,Spring將搜索關(guān)聯(lián)的線程池定義:上下文中的唯一org.springframework.core.task.TaskExecutor

的bean,或者名為taskExecutor的java.util.concurrent.Executor

的bean。如果兩者都無法解析,則將使用org.springframework.core.task.SimpleAsyncTaskExecutor來處理異步方法調(diào)用。

TaskExecutor實現(xiàn)為每個任務(wù)啟動一個新線程,異步執(zhí)行它。支持通過concurrencyLimitbean屬性限制并發(fā)線程。默認情況下,并發(fā)線程數(shù)是無限的,所以使用默認的線程池有導(dǎo)致內(nèi)存溢出的風(fēng)險。

注意:剛才的運行結(jié)果看起來是線程復(fù)用的,而實際上此實現(xiàn)不重用線程!應(yīng)盡量實現(xiàn)一個線程池TaskExecutor,特別是用于執(zhí)行大量短期任務(wù)。不要使用默認的SimpleAsyncTaskExecutor。

importorg.springframework.context.annotation.Bean;

importorg.springframework.scheduling.annotation.Async;

importorg.springframework.scheduling.annotation.EnableAsync;

importorg.springframework.scheduling.annotation.EnableScheduling;

importorg.springframework.scheduling.annotation.Scheduled;

importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

importorg.springframework.stereotype.Component;

importjava.time.LocalDateTime;

importjava.util.concu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論