Spring的兩種任務調度Scheduled和Async

Spring提供了兩種后臺任務的方法,分別是:

  1. 調度任務,@Schedule
  2. 異步任務,@Async

當然,使用這兩個是有條件的,需要在spring應用的上下文中聲明
<task:annotation-driven/>當然,如果我們是基于java配置的,需要在配置哪里加多EnableScheduling@EnableAsync?就像下面這樣

1
2
3
4
5
6
@EnableScheduling
@EnableAsync
public class WebAppConfig {
....

除此之外,還是有第三方庫可以調用的,例如Quartz.


@Schedule

先看下@Schedule怎么調用再說

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public?final?static?long ONE_DAY =?24 *?60 *?60 *?1000;
public?final?static?long ONE_HOUR =?60 *?60 *?1000;
@Scheduled(fixedRate = ONE_DAY)
public?void?scheduledTask() {
System.out.println(" 我是一個每隔一天就會執行一次的調度任務");
}
@Scheduled(fixedDelay = ONE_HOURS)
public?void?scheduleTask2() {
System.out.println(" 我是一個執行完后,隔一小時就會執行的任務");
}
@Scheduled(initialDelay=1000, fixedRate=5000)
public?void?doSomething() {
// something that should execute periodically
}
@Scheduled(cron =?"0 0/1 * * * ? ")
public?void?ScheduledTask3() {
System.out.println(" 我是一個每隔一分鐘就就會執行的任務");
}

需要注意的

  1. 關于最后一個,在指定時間執行的任務,里面使用的是Cron表達式,同時我們看到了兩個不一樣的面孔fixedDelay&?fixedRate,前者fixedDelay表示在指定間隔運行程序,例如這個程序在今晚九點運行程序,跑完這個方法后的一個小時,就會再執行一次,而后者fixedDelay者是指,這個函數每隔一段時間就會被調用(我們這里設置的是一天),不管再次調度的時候,這個方法是在運行還是結束了。而前者就要求是函數運行結束后開始計時的,這就是兩者區別。

  2. 這個還有一個initialDelay的參數,是第一次調用前需要等待的時間,這里表示被調用后的,推遲一秒再執行,這適合一些特殊的情況。

  3. 我們在serviceImpl類寫這些調度任務時候,也需要在這些我們定義的serviceInterface的借口中寫多這個接口,要不然會爆?but not found in any interface(s) for bean JDK proxy.Either pull the method up to an interface or

@Async

有時候我們會調用一些特殊的任務,任務會比較耗時,重要的是,我們不管他返回的后果。這時候我們就需要用這類的異步任務啦,調用后就讓他去跑,不堵塞主線程,我們繼續干別的。代碼像下面這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public?void?AsyncTask(){
@Async
public?void?doSomeHeavyBackgroundTask(int sleepTime) {
try {
Thread.sleep(sleepTime);
}?catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async
public Future<String>?doSomeHeavyBackgroundTask() {
try {
Thread.sleep(3000);
}?catch (InterruptedException e) {
e.printStackTrace();
}
return?null;
}
public?void?printLog() {
System.out.println(" i print a log ,time=" + System.currentTimeMillis());
}
}

我們寫個簡單的測試類來測試下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = AsycnTaskConfig.class)?//要聲明@EnableASync
public class AsyncTaskTest {
@Autowired
AsyncTask asyncTask;
@Test
public void AsyncTaskTest() throws InterruptedException {
if (asyncTask != null) {
asyncTask.doSomeHeavyBackgroundTask(4000);
asyncTask.printLog();
Thread.sleep(5000);
}
}
}

這感覺比我們手動開多一個線程方便多了,不想異步的話直接把@Async去掉就可以了,另外如果你想要返回個結果的,這需要加多個Future<>,關于這個Future,完全可以寫多幾篇文章介紹,順便把FutureTask介紹了。如果想修改Spring boot的默認線程池配置,可以實現AsyncConfigurer.
需要注意的:

  1. 相對于@scheduled,這個可以有參數和返回個結果,因為這個是我們調用的,而調度的任務是spring調用的。
  2. 異步方法不能內部調用,只能像上面那樣,外部調用,否則就會變成阻塞主線程的同步任務啦!這個坑我居然跳下去了!例如下面這樣的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public?void?AsyncTask(){
public?void?fakeAsyncTaskTest(){
doSomeHeavyBackgroundTask(4000);
printLog();
//你會發現,當你像這樣內部調用的時候,居然是同步執行的,不是異步的!!
}
@Async
public?void?doSomeHeavyBackgroundTask(int sleepTime) {
try {
Thread.sleep(sleepTime);
}?catch (InterruptedException e) {
e.printStackTrace();
}
}
public?void?printLog() {
System.out.println(" i print a log ");
}
}
  1. 另外一點就是不要重復的掃描,這也會導致異步無效,具體的可以看這個stackoveflow的spring-async-not-working?Issue。
  2. 關于異常處理,難免在這個異步執行過程中有異常發生,對于這個問題,spring提供的解決方案如下,實現 AsyncUncaughtExceptionHandler接口。
1
2
3
4
5
6
7
8
9
10
11
public?class?MyAsyncUncaughtExceptionHandler?implements
AsyncUncaughtExceptionHandler {
@Override
public?void?handleUncaughtException(Throwable ex,
Method method, Object... params) {
// handle exception
}
}

寫好我們的異常處理后,我們需要配置一下,告訴spring,這個異常處理就是我們在運行異步任務時候,拋出錯誤時的異常終結者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
@EnableAsync
public?class?AsyncConfig?implements?AsyncConfigurer {
@Bean
public AsyncTask?asyncBean() {
return?new AsyncTask();
}
@Override
public Executor?getAsyncExecutor() {
ThreadPoolTaskExecutor executor =?new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler?getAsyncUncaughtExceptionHandler() {
return?new MyAsyncUncaughtExceptionHandler();
}
}

Quartz登場

處理這兩個外,還有一個和spring整合的第三方庫叫Quartz
看了下官網的使用簡介,也是挺逗的,現在都習慣用maven,gradle之類來關系這些依賴了,他還叫人下載,也是不知為何,詳情點擊->
http://quartz-scheduler.org/documentation/quartz-2.2.x/quick-start
估計有可能是因為沒再維護了的原因吧,看了下,最新版2.2居然是Sep, 2013更新的…
居然是停更的,不過Quartz作為一個企業級應用的任務調度框架,還是一個可以的候選項目的。
這里不鋪開講,有興趣就去官網看下吧。整體用起來感覺是沒有spring自己的后臺任務方便,不過也可以接受,只需要簡單的配置就可以使用了。

http://www.cnblogs.com/slimer/p/6401394.html

?

轉載于:https://www.cnblogs.com/softidea/p/6855034.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/541373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/541373.shtml
英文地址,請注明出處:http://en.pswp.cn/news/541373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

建立單鏈表 單鏈表的插入_單鏈列表插入

建立單鏈表 單鏈表的插入All possible cases: 所有可能的情況&#xff1a; Inserting at beginning 開始插入 Inserting at the ending 在末尾插入 Inserting at given position 在給定位置插入 Algorithms: 算法&#xff1a; 1)開始插入 (1) Inserting at the beginning) In…

mysql學習筆記(1-安裝簡介)

mysql的安裝方式&#xff1a;(1)通過系統提供的默認版本(rpm包&#xff0c;穩定版&#xff0c;該版本滿足了使用的需求&#xff0c;建議使用&#xff0c;os vendor)(2)mysql官方提供官方提供的通用rpm安裝包通用二進制格式的程序包(直接下載文件&#xff0c;解壓到指定目錄&…

存儲器間接尋址方式_8086中的數據存儲器尋址模式

存儲器間接尋址方式In this type of addressing mode, first the offset address is calculated, then the memory address is calculated and then the operand form that memory location is fetched. There are following modes which lie under the Data Addressing Mode: …

oracle asm 刪除diskgroup,ASM磁盤組刪除DISK操作

沒想到這么簡單的操作&#xff0c;由于不熟悉還碰到了兩個小問題。[oracledbserver1 ~]$ sqlplus / as sysdbaSQL*Plus: Release 11.2.0.2.0 Production on Tue Aug 9 10:08:062011Copyright (c) 1982, 2010, Oracle.All rights reserved.Connected to:Oracle Database 11g Ent…

intellij idea 最常用的快捷鍵

F2&#xff0c; 可以快速的向下跳走 CtrlF7&#xff0c;可以查詢當前元素在當前文件中的引用&#xff0c;然后按 F3 可以選擇AltQ&#xff0c;可以看到當前方法的聲明CtrlP&#xff0c;可以顯示參數信息CtrlAltV&#xff0c;可以引入變量。例如&#xff1a;new String(); 自動導…

如何在Java中檢查字符串是否為數字?

We will check whether string is a number or not – with the help of logic we will solve this problem, 我們將檢查字符串是否為數字-借助邏輯&#xff0c;我們將解決此問題&#xff0c; In the first step, we will take a string variable named str and store any val…

oracle清理告警日志,Oracle 跟蹤/告警/監聽日志的清理腳本

[root ~]# cat del_oracle_log.sh#!/bin/bashsource /home/oracle/.bash_profilefunction audit_log(){ #---audit_log日志跟蹤文件#audit_log$(strings $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora|grep -i audit_file_dest|awk -F {print $NF}|sed "s///g")audit_lo…

python爬蟲之scrapy框架

Scrapy是一個為了爬取網站數據&#xff0c;提取結構性數據而編寫的應用框架。 其可以應用在數據挖掘&#xff0c;信息處理或存儲歷史數據等一系列的程序中。其最初是為了頁面抓取 (更確切來說, 網絡抓取 )所設計的&#xff0c; 也可以應用在獲取API所返回的數據(例如 Amazon As…

oracle中的事務回滾,ORACLE 死事務的回滾

死事務出現在異常關閉數據庫或者事務進程不正常結束&#xff0c;比如KILL -9&#xff0c;shutdown abort的情況下。當前數據庫里的死事務可以通過查詢內部表x$ktuxe來獲得。select ADDR,KTUXEUSN,KTUXESLT,KTUXESQN,KTUXESIZ from x$ktuxe where KTUXECFLDEAD;ADDR …

大數據數據可視化設計原則_數據可視化設計的8頂帽子

大數據數據可視化設計原則8 hats of data visualization are basically the important persons and their roles that are basically required to carry out data visualization are as follows: 數據可視化有8個基本要素&#xff0c;而進行數據可視化所需的基本角色如下&#…

debian8.8安裝谷歌瀏覽器

第一步&#xff1a;下載&#xff1a; wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb //32位 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb //64位第二步&#xff1a;安裝dpkg -i google-chrome*.deb…

MB_LEN_MAX常數,帶C ++示例

C MB_LEN_MAX宏常量 (C MB_LEN_MAX macro constant) MB_LEN_MAX constant is a macro constant which is defied in climits header, it is used to get the maximum number of bytes in a multibyte character, for any locale, it returns maximum number of bytes that a m…

php谷歌收錄接口,php實現查詢百度google收錄情況(示例代碼)

PHP$SEOdetail array();$domain !empty($_GET[q]) ? $_GET[q] : www.mycodes.net;baidudetail($domain);googledetail($domain);var_dump($SEOdetail);function baidudetail($domain) {$baidu_site http://www.baidu.com/baidu?wordsite%3A . $domain;$baidu_link http:/…

Linux學習第三步(Centos7安裝mysql5.7數據庫)

版本&#xff1a;mysql-5.7.16-1.el7.x86_64.rpm-bundle.tar 前言&#xff1a;在linux下安裝mysql不如windows下面那么簡單&#xff0c;但是也不是很難。本文向大家講解了如何在Centos7下如何安裝mysql5.7版本,如果有什么問題和錯誤的地方&#xff0c;歡迎大家指出。 注釋&…

linux oracle刪除恢復數據恢復,Linux下Oracle誤刪除數據文件恢復操作

檢查數據文件的位置如下&#xff1a;SQL> select name from v$datafile;NAME--------------------------------------------------------------------------------/u01/app/Oracle/oradata/marven/system01.dbf/u01/app/oracle/oradata/marven/undotbs1.dbf/u01/app/oracle/…

數據庫如何處理數據庫太大_網絡數據庫中的數據處理

數據庫如何處理數據庫太大Before learning the data manipulation in a network model, we are discussing data manipulation language, so what is the data manipulation language? 在學習網絡模型中的數據操作之前&#xff0c;我們正在討論數據操作語言&#xff0c;那么什…

oracle12537錯誤,ORA-12537:TNS:connection closed錯誤處理方法

1.ORA-12537:TNS:connection closed錯誤處理過程檢查監聽正常&#xff0c;Oracle服務也是正常啟動的&#xff0c;但是登錄不進去。2.解決方案1. cd $ORACLE_HOME/bin/ 進入bin目錄2. ll oracle-rwxrwxrwx. 1 ora12 dba 323762222 6?. 14 19:12 oracle3.chmod 6571 oracle 更改…

操作系統中的死鎖_操作系統中的死鎖介紹

操作系統中的死鎖1.1究竟什么是僵局&#xff1f; (1.1 What exactly is a deadlock?) In a multiprogramming environment, there may be several processes with a finite number of resources. A process may request another resource while still holding some of the oth…

《云數據管理:挑戰與機遇》2.3 數據庫系統

本節書摘來自華章出版社《云數據管理》一書中的第2章&#xff0c;第3節&#xff0c;作者迪衛艾肯特阿格拉沃爾&#xff0c;更多章節內容可以訪問云棲社區“華章計算機”公眾號查看本節中&#xff0c;我們將為數據庫系統中的一些主要概念提供一個相當抽象、簡潔和高層次的描述。…