java定時器
阿新 • • 發佈:2022-04-11
一、@Scheduled註解
這是基於註解可實現定時任務。
實現:
1、
@EnableScheduling註解到定時方法的類上,或者直接註解到啟動類。
2、
@Scheduled註解到定時方法上
@Scheduled有以下引數:
1 @Scheduled(fixedDelay = 3000) //方法執行完成後等待3秒再次執行 2 @Scheduled(fixedRate = 3000) //方法每隔3秒執行一次 3 @Scheduled(initialDelay = 2000,fixedRate = 4000) //延遲2秒執行第一次,之後每隔4秒執行一次 4 @Scheduled(fixedDelayString ="${time.demo}") //可以執行配置檔案中的,方法執行完成後等待time.demo再次執行 5 @Scheduled(fixedRateString ="${time.demo}" ) //可以執行配置檔案中的,法每隔time.demo執行一次 6 @Scheduled(cron = "0 0,30 0,8 ? * ? ") //cron表示式,方法在每天的8點30分0秒執行,引數為字串型別
cron表示式,推薦看這篇文章:https://www.jianshu.com/p/1defb0f22ed1
示例:
每隔3秒執行一次。
1 @Component 2 @EnableScheduling 3 public class testScheduled {4 5 @Scheduled(fixedRate = 3000) 6 public void call(){ 7 System.out.println("每隔3秒列印一次"); 8 } 9 }
優點:簡單,只需要兩個註解即可
缺點:引數和方法都必須寫到程式碼裡面
二、Timer().schedule建立任務
直接上示例,2秒後執行第一次,然後每隔4秒執行一次。
1 @Component 2 public class testTimer { 3 { 4 doTimer(); 5 } 6 publicvoid doTimer(){ 7 //建立timer物件 8 Timer timer = new Timer(); 9 //建立TimerTask物件 10 TimerTask timerTask = new TimerTask() { 11 //重寫run方法,就是具體定時做什麼事情 12 @Override 13 public void run() { 14 System.out.println(new Date().toString()); 15 } 16 }; 17 //timer來執行timerTask 18 timer.schedule(timerTask,2000,4000); 19 } 20 }
幾個概念:
Timer:即定時器,為java自帶的工具類,提供定時執行任務的相關功能
timer有3個核心方法:
1、新增任務(6種)
schedule(TimerTask task, long delay):指定任務task,在delay毫秒延遲後執行 schedule(TimerTask task, Date time):指定任務task,在time時間點執行一次 schedule(TimerTask task, long delay, long period):指定任務task,延遲delay毫秒後執行第一次,並在之後每隔period毫秒執行一次 schedule(TimerTask task, Date firstTime, long period):指定任務task,在firstTime的時候執行第一次,之後每隔period毫秒執行一次 scheduleAtFixedRate(TimerTask task, long delay, long period):作用與schedule一致 scheduleAtFixedRate(TimerTask task, Date firstTime, long period):作用與schedule一致 實際上最後都會使用sched(TimerTask task, long time, long period),即指定任務task,在time執行第一次,之後每隔period毫秒執行一次 schedule使用系統時間計算下一次,即System.currentTimeMillis()+period 而scheduleAtFixedRate使用本次預計時間計算下一次,即time + period 對於耗時任務,兩者區別較大,請按需求選擇,瞬時任務無區別。
2、取消任務方法:cancel(),會將任務佇列清空,並堵塞執行緒,且不再能夠接受任務(接受時報錯),並不會銷燬本身的例項和其內部的執行緒。
3、淨化方法:purge(),淨化會將佇列裡所有被取消的任務移除,對剩餘任務進行堆排序,並返回移除任務的數量。
TimerTask:實際上就是一個Runnable而已,繼承Runnable並添加了幾個自定義的引數和方法,說白了就是在這裡面寫定時的具體方法。
TaskQueue:即任務佇列,Timer生產任務,然後推到TaskQueue裡存放,等待處理,被處理掉的任務即被移除掉。
注:TaskQueue
實質上只有一個長度為128的陣列用於儲存TimerTask
、一個int型變數size表示佇列長度、以及對這兩個資料的增刪改查。
TimerThread:即定時器執行緒,執行緒會共享TaskQueue裡面的資料,TimerThread會對TaskQueue裡的任務進行消耗。
注:TimerThread
實際上就是一個Thread
執行緒,會不停的監聽TaskQueue
,如果佇列裡面有任務,那麼就執行第一個,並將其刪除(先刪除再執行)。
三、執行緒
1、通過執行緒的sleep來造成延時的效果
示例1:thread + runnable
1 @Component 2 public class testThreadAndRunnable { 3 4 private Integer count = 0; 5 6 public testThreadAndRunnable() { 7 test1(); 8 } 9 public void test1() { 10 new Thread(() -> { 11 while (count < 10) { 12 System.out.println(new Date().toString() + ": " + count); 13 count++; 14 try { 15 Thread.sleep(3000); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 } 20 }).start(); 21 } 22 }
示例2:執行緒池 + runnable
1 @Component 2 public class testThreadPool { 3 private static final ExecutorService threadPool = Executors.newFixedThreadPool(5);// 執行緒池 4 private Integer count = 0; 5 public testThreadPool() { 6 test2(); 7 } 8 public void test2() { 9 threadPool.execute(() -> { 10 while (count < 10) { 11 System.out.println(new Date().toString() + ": " + count); 12 count++; 13 try { 14 Thread.sleep(3000); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 } 19 }); 20 } 21 }
2、使用ScheduledTask + runnable
示例:
@Component public class testScheduledTask { private Integer count = 0; @Autowired private TaskScheduler taskScheduler; public testScheduledTask(TaskScheduler taskScheduler) { this.taskScheduler = taskScheduler; test4(); test5(); test6(); } //設定間隔時間,每2秒執行一次 public void test4() { taskScheduler.scheduleAtFixedRate(() -> { System.out.println(new Date().toString() + ": " + count+"設定間隔時間2秒"); count++; }, 2000); } //可以用Cron表示式,每天凌晨1點執行 public void test5() { taskScheduler.schedule(() -> { System.out.println(new Date().toString() + ": " + count+"凌晨1點執行"); count++; }, new CronTrigger("0 0 1 * * ?")); } //設定間隔時間,每5.5秒執行一次 public void test6() { taskScheduler.scheduleAtFixedRate(() -> { System.out.println(new Date().toString() + ": " + count+"設定間隔時間5.5秒"); count++; }, 5500); } }
參考部落格:(118條訊息) 【JAVA定時器】四種常見定時器的原理和簡單實現_Echo-YeZi的部落格-CSDN部落格_java 定時器