<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在使用定時任務的時候發現,自己寫的定時任務沒有執行,後來查了上網查了一下,才知道@Scheduled註解的定時任務是單執行緒的,同一時間段內只能執行一個定時任務,其它定時任務不執行。
需要設定@Scheduled多執行緒支援,才能實現同一時間段內,執行多個定時任務。
一般情況下面兩個定時任務只會執行第一個定時任務,第二個定時任務不會執行。
/** * 測試定時任務1 每天22:00:00執行 */ @Scheduled(cron = "0 0 22 * * ?") public void test() { for (int i = 0; i < 20; i++) { try { Thread.sleep(1000 * 10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=======================測試定時任務執行1======================="); } } /** * 測試定時任務2 每天22:10:00執行 */ @Scheduled(cron = "0 10 22 * * ?") public void test2() { for (int i = 0; i < 20; i++) { try { Thread.sleep(1000 * 10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=======================測試定時任務執行2======================="); } }
要解決上訴問題,就需要設定 @Scheduled多執行緒支援,新增一個設定類,程式碼如下:
/** * @description: 使@schedule支援多執行緒的設定類 * @author: David Allen * @create: 2020-12-08 **/ @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { Method[] methods = Job.class.getMethods(); int defaultPoolSize = 3; int corePoolSize = 0; if (!CollectionUtils.isEmpty(Arrays.asList(methods))) { for (Method method : methods) { Scheduled annotation = method.getAnnotation(Scheduled.class); if (annotation != null) { corePoolSize++; } } if (defaultPoolSize > corePoolSize) { corePoolSize = defaultPoolSize; } taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize)); } } }
@Scheduled註解會在預設情況下以單執行緒的方式執行定時任務。
這個“單執行緒”指兩個方面:
那麼這種效果肯定不是我們想要的,為了使@Scheduled效率更高,我們可以通過兩種方法將定時任務變成多執行緒執行:
1、在啟動類中設定TaskScheduler執行緒池大小
@Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(50); return taskScheduler; }
2、利用Spring提供的@Async註解和@EnableAsync註解
@Component @EnableAsync public class TimedTask{ @Async @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執行一次 public void taskA() { //執行你的業務邏輯 } @Async @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執行一次 public void taskB() { //執行你的業務邏輯 }
通過以上方式,定時任務將會以多執行緒的方式開始執行,減小了程式耦合度,提升執行效率。
定時任務在同一時刻開始執行有兩種情況:
由於任務都是非同步的,如果多個任務同時操作同一資源,那麼必然會導致錯誤。
這個時候可以給任務加鎖,保證任務互不干擾,擁有在同一時刻執行的執行緒安全:
@Component @EnableAsync public class TimedTask{ private Object lock = new Object(); @Async @Scheduled(cron = "0 0 0 * * ?")//每天零點執行 public void taskA() { synchronized(lock){ //執行你的業務邏輯 } } @Async @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執行一次 public void taskB() { synchronized(lock){ //執行你的業務邏輯 } }
如果對執行順序有要求的定時任務,有如下兩種情況:
1、在某一時刻同時執行
如任務A在零點初始化資料,任務B每分鐘更新資料。那麼在零點,必須是任務A先執行,其次才是B。但加鎖只能保證執行緒安全,不能保證執行順序。在這種情況下,我們可以藉助redis設定獲取鎖的順序,亦或標誌字進行執行順序的判斷。
2、總是同時執行
在任務間隔相同的情況下,一般為業務的解耦,不應操作共用資源,應當放至同一個定時任務中執行。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45