javascript
Spring的两种任务调度Scheduled和Async
Spring提供了兩種后臺任務(wù)的方法,分別是:
當(dāng)然,使用這兩個是有條件的,需要在spring應(yīng)用的上下文中聲明
<task:annotation-driven/>當(dāng)然,如果我們是基于java配置的,需要在配置哪里加多EnableScheduling和@EnableAsync?就像下面這樣
| 1 2 3 4 5 6 | @EnableScheduling @EnableAsync public class WebAppConfig { .... } |
除此之外,還是有第三方庫可以調(diào)用的,例如Quartz.
@Schedule
先看下@Schedule怎么調(diào)用再說
| 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; public?void?scheduledTask() { System.out.println(" 我是一個每隔一天就會執(zhí)行一次的調(diào)度任務(wù)"); } public?void?scheduleTask2() { System.out.println(" 我是一個執(zhí)行完后,隔一小時就會執(zhí)行的任務(wù)"); } public?void?doSomething() { // something that should execute periodically } public?void?ScheduledTask3() { System.out.println(" 我是一個每隔一分鐘就就會執(zhí)行的任務(wù)"); } |
需要注意的
關(guān)于最后一個,在指定時間執(zhí)行的任務(wù),里面使用的是Cron表達式,同時我們看到了兩個不一樣的面孔fixedDelay&?fixedRate,前者fixedDelay表示在指定間隔運行程序,例如這個程序在今晚九點運行程序,跑完這個方法后的一個小時,就會再執(zhí)行一次,而后者fixedDelay者是指,這個函數(shù)每隔一段時間就會被調(diào)用(我們這里設(shè)置的是一天),不管再次調(diào)度的時候,這個方法是在運行還是結(jié)束了。而前者就要求是函數(shù)運行結(jié)束后開始計時的,這就是兩者區(qū)別。
這個還有一個initialDelay的參數(shù),是第一次調(diào)用前需要等待的時間,這里表示被調(diào)用后的,推遲一秒再執(zhí)行,這適合一些特殊的情況。
我們在serviceImpl類寫這些調(diào)度任務(wù)時候,也需要在這些我們定義的serviceInterface的借口中寫多這個接口,要不然會爆?but not found in any interface(s) for bean JDK proxy.Either pull the method up to an interface or
@Async
有時候我們會調(diào)用一些特殊的任務(wù),任務(wù)會比較耗時,重要的是,我們不管他返回的后果。這時候我們就需要用這類的異步任務(wù)啦,調(diào)用后就讓他去跑,不堵塞主線程,我們繼續(xù)干別的。代碼像下面這樣:
| 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(){ public?void?doSomeHeavyBackgroundTask(int sleepTime) { try { Thread.sleep(sleepTime); }?catch (InterruptedException e) { e.printStackTrace(); } } 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去掉就可以了,另外如果你想要返回個結(jié)果的,這需要加多個Future<>,關(guān)于這個Future,完全可以寫多幾篇文章介紹,順便把FutureTask介紹了。如果想修改Spring boot的默認(rèn)線程池配置,可以實現(xiàn)AsyncConfigurer.
需要注意的:
| 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(); //你會發(fā)現(xiàn),當(dāng)你像這樣內(nèi)部調(diào)用的時候,居然是同步執(zhí)行的,不是異步的!! } 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 2 3 4 5 6 7 8 9 10 11 | public?class?MyAsyncUncaughtExceptionHandler?implements AsyncUncaughtExceptionHandler { public?void?handleUncaughtException(Throwable ex, Method method, Object... params) { // handle exception } } |
寫好我們的異常處理后,我們需要配置一下,告訴spring,這個異常處理就是我們在運行異步任務(wù)時候,拋出錯誤時的異常終結(jié)者
| 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 | public?class?AsyncConfig?implements?AsyncConfigurer { public AsyncTask?asyncBean() { return?new AsyncTask(); } public Executor?getAsyncExecutor() { ThreadPoolTaskExecutor executor =?new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.setThreadNamePrefix("MyExecutor-"); executor.initialize(); return executor; } public AsyncUncaughtExceptionHandler?getAsyncUncaughtExceptionHandler() { return?new MyAsyncUncaughtExceptionHandler(); } } |
Quartz登場
處理這兩個外,還有一個和spring整合的第三方庫叫Quartz
看了下官網(wǎng)的使用簡介,也是挺逗的,現(xiàn)在都習(xí)慣用maven,gradle之類來關(guān)系這些依賴了,他還叫人下載,也是不知為何,詳情點擊->
http://quartz-scheduler.org/documentation/quartz-2.2.x/quick-start
估計有可能是因為沒再維護了的原因吧,看了下,最新版2.2居然是Sep, 2013更新的…
居然是停更的,不過Quartz作為一個企業(yè)級應(yīng)用的任務(wù)調(diào)度框架,還是一個可以的候選項目的。
這里不鋪開講,有興趣就去官網(wǎng)看下吧。整體用起來感覺是沒有spring自己的后臺任務(wù)方便,不過也可以接受,只需要簡單的配置就可以使用了。
http://www.cnblogs.com/slimer/p/6401394.html
?
轉(zhuǎn)載于:https://www.cnblogs.com/softidea/p/6855034.html
總結(jié)
以上是生活随笔為你收集整理的Spring的两种任务调度Scheduled和Async的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简述container与containe
- 下一篇: 20个编写现代CSS代码的建议