在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    Quartz 的執(zhí)行流程分析

    Quartz 的執(zhí)行流程分析

    一、QuartzSchedulerThread 的 run方法大致闡述

    先說一下run方法的執(zhí)行時機:

    當(dāng) Quartzscheduler執(zhí)行start方法 時,方法體中有一句

    schedThread.togglePause(false); ,接著就會調(diào)用 QuartzSchedulerThread 下的 togglePause 方法,將 paused 置為 false ,在此之后, QuartzSchedulerThread 下的 run 方法開始真正運行

    /**通知主處理循環(huán)在下一個可能的點暫停 */ void togglePause(boolean pause) { synchronized (sigLock) { paused = pause; if (paused) { signalSchedulingChange(0); } else { sigLock.notifyAll(); } } }復(fù)制代碼 public void run() { int acquiresFailed = 0; // 這里就是判斷調(diào)度器是否該停止,如果沒有收到信號的話,這個調(diào)度器是一直處于循環(huán)之中的 while (!halted.get()) { try { // 這里是檢查我們是否應(yīng)該暫停 synchronized (sigLock) { // 我們在初始化的時候,paused 是置為 true的, // 因此在上文中,我們才說 // 當(dāng) Quartzscheduler 執(zhí)行 start方法時調(diào)用togglePause, // 將 paused 置為false,run 方法才開始運行 // 也是因為此處的判斷 while (paused && !halted.get()) { try { sigLock.wait(1000L); }catch (InterruptedException ignore) {} acquiresFailed = 0; } if (halted.get()) { break;} } // 如果從作業(yè)存儲中讀取一直失敗(例如數(shù)據(jù)庫關(guān)閉或重新啟動) // 就會等待一段時間~ if (acquiresFailed > 1) { try { //這里就是計算延遲時間 long delay = computeDelayForRepeatedErrors(qsRsrcs.getJobStore(), acquiresFailed); Thread.sleep(delay); } catch (Exception ignore) {} } // 從線程池拿出空閑可利用的線程數(shù)量 // 這里多談一嘴 blockForAvailableThreads()方法 // 它是一個阻塞式方法,直到至少有一個可用線程。 int availThreadCount = qsRsrcs.getThreadPool().blockForAvailableThreads(); if(availThreadCount > 0) { List triggers; long now = System.currentTimeMillis(); // 清除信號調(diào)度變更 clearSignaledSchedulingChange(); try { //如果可用線程數(shù)量足夠那么就是30后再次掃描, //acquireNextTriggers方法的三個參數(shù)的意思分別是: //idleWaitTime :為如果沒有的再次掃描的時間,默認(rèn)是 // private static long DEFAULT_IDLE_WAIT_TIME = 30L * 1000L; 30秒 //Math.min(availThreadCount, qsRsrcs.getMaxBatchSize()) :這里的意思就是一次最多能取幾個出來 //batchTimeWindow :默認(rèn)是0,同樣是一個時間范圍, //如果有兩個任務(wù)只差一兩秒,而執(zhí)行線程數(shù)量滿足及batchTimeWindow時間也滿足的情況下就會兩個都取出來 // 具體的方法的執(zhí)行,后文再看~ triggers = qsRsrcs.getJobStore().acquireNextTriggers( now + idleWaitTime, Math.min(availThreadCount, qsRsrcs.getMaxBatchSize()), qsRsrcs.getBatchTimeWindow()); acquiresFailed = 0; if (log.isDebugEnabled()){ //… } //在獲取到 triggers 觸發(fā)器不為空后, //trigger列表是以下次執(zhí)行時間排序查出來的 if (triggers != null && !triggers.isEmpty()) { now = System.currentTimeMillis(); //取出集合中最早執(zhí)行的觸發(fā)器 //獲取它的下一個觸發(fā)時間 long triggerTime = triggers.get(0).getNextFireTime().getTime(); long timeUntilTrigger = triggerTime – now; // 判斷距離執(zhí)行時間是否大于2 毫秒 while(timeUntilTrigger > 2) { synchronized (sigLock) { if (halted.get()) { break; } //判斷是不是距離觸發(fā)事件最近的, if (!isCandidateNewTimeEarlierWithinReason(triggerTime, false)) { try { // 沒有的話,就進(jìn)行阻塞,稍后進(jìn)行執(zhí)行 now = System.currentTimeMillis(); timeUntilTrigger = triggerTime – now; if(timeUntilTrigger >= 1) sigLock.wait(timeUntilTrigger); } catch (InterruptedException ignore) {} } } if(releaseIfScheduleChangedSignificantly(triggers, triggerTime)) { break; } now = System.currentTimeMillis(); timeUntilTrigger = triggerTime – now; } // this happens if releaseIfScheduleChangedSignificantly decided to release triggers if(triggers.isEmpty()) continue; // set triggers to ‘executing’ List bndles = new ArrayList(); boolean goAhead = true; synchronized(sigLock) { goAhead = !halted.get(); } if(goAhead) { try { //開始根據(jù)需要執(zhí)行的trigger從數(shù)據(jù)庫中獲取相應(yīng)的JobDetail 同時這一步也更新了 triggers 的狀態(tài),稍后會講到~ List res = qsRsrcs.getJobStore().triggersFired(triggers); if(res != null) bndles = res; } catch (SchedulerException se) { qs.notifySchedulerListenersError( “An error occurred while firing triggers ‘” + triggers + “‘”, se); for (int i = 0; i < triggers.size(); i++) { qsRsrcs.getJobStore().releaseAcquiredTrigger(triggers.get(i)); } continue; } } //將查詢到的結(jié)果封裝成為 TriggerFiredResult for (int i = 0; i 0) // should never happen, if threadPool.blockForAvailableThreads() follows contract continue; // while (!halted) } long now = System.currentTimeMillis(); long waitTime = now + getRandomizedIdleWaitTime(); long timeUntilContinue = waitTime – now; synchronized(sigLock) { // …. } } // …. } // while (!halted) // …. }復(fù)制代碼

    二、一些細(xì)節(jié)

    2.1、先獲取線程池中的可用線程數(shù)量

    (若沒有可用的會阻塞,直到有可用的);

    int availThreadCount = qsRsrcs.getThreadPool().blockForAvailableThreads(); 復(fù)制代碼

    2.2、獲取 30m 內(nèi)要執(zhí)行的 trigger

    (即 acquireNextTriggers )

    我們來看一看 acquireNextTriggers 方法

    首先說 acquireNextTriggers 具體實現(xiàn)是在 JobStoreSupport 中,同時 quartz 與數(shù)據(jù)庫關(guān)聯(lián)的實現(xiàn)大都在 JobStoreSupport 中,當(dāng)然更具體的SQL執(zhí)行還是在 DriverDelegate 接口下的。

    acquireNextTriggers 做了哪些事情呢?

    我們看看這兩個方法:

    首先看第一個 acquireNextTrigger(conn, noLaterThan, maxCount, timeWindow);

    主要就是獲取下一個 30m內(nèi)可執(zhí)行的triggers的觸發(fā)器,在里面 JobStoreSupport 從數(shù)據(jù)庫取出 triggers 時是按照 nextFireTime 排序的

    更具體的就需要大家點進(jìn)方法去看啦~另外里面還包含triggers狀態(tài)的變更,屬于是更加細(xì)節(jié)化的東西。

    第二個就是獲取到觸發(fā)的觸發(fā)記錄~

    然后在執(zhí)行 executeInNonManagedTXLock 時,是需要先獲得鎖,之后再在提交時釋放鎖的。

    待直到獲取的trigger中最先執(zhí)行的trigger在2ms內(nèi);

    if (triggers != null && !triggers.isEmpty()) { now = System.currentTimeMillis(); long triggerTime = triggers.get(0).getNextFireTime().getTime(); long timeUntilTrigger = triggerTime – now; while(timeUntilTrigger > 2) { //… } }復(fù)制代碼

    2.3、triggersFired(triggers)

    List res = qsRsrcs.getJobStore().triggersFired(triggers);

    這一步看著只是獲取了 List 對象,實際上在 triggersFired(triggers) 方法中隱藏了很多東西~

    首先查詢,確保觸發(fā)器沒有被刪除、暫?;蛲瓿?#8230;,就更新 firedTrigger 的 status=STATE_EXECUTING ;代碼的注釋上還說,如果沒有這些就會將狀態(tài)該為 deleted

    另外就是更新觸發(fā)觸發(fā)器:

  • 更新trigger下一次觸發(fā)的時間;
  • 更新trigger的狀態(tài):
  • 如果下一次的執(zhí)行時間為空,狀態(tài)則改為 STATE_COMPLETE

    在執(zhí)行 executeInNonManagedTXLock 方法時,提交前先獲得鎖, transOwner = getLockHandler().obtainLock(conn, lockName);

    最后是釋放鎖: commitConnection(conn);

    2.4、創(chuàng)建JobRunShell,放進(jìn)線程池執(zhí)行

    針對每個要執(zhí)行的trigger,創(chuàng)建JobRunShell,并放入線程池執(zhí)行:

    然后由execute:執(zhí)行job

    更詳細(xì)的看不下去啦~

    來源:https://juejin.cn/post/7131671438901116935

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年8月16日 09:34
    下一篇 2022年8月16日 09:34

    相關(guān)推薦

    • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

      對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個朋友圈,有的微商看起來逼格滿滿,實際效果也不錯;而有的卻動都不動就被屏蔽甚至拉黑…

      2022年11月27日
    • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

      寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

      2022年11月25日
    • 5+3疫情防控從哪天開始算(遼寧疫情防控最新政策)

      最近有關(guān)國內(nèi)各地的疫情大家也都有在持續(xù)關(guān)注,目前國內(nèi)各地疫情隔離時間也根據(jù)二十條防控措施有了新的調(diào)整。那么,5+3疫情防控從哪天開始算?對于密接的5+3隔離時間計算大家還是比較關(guān)心…

      2022年11月25日
    • 藍(lán)碼怎么變綠碼需要幾天(藍(lán)碼怎么變綠碼需要幾天)

      大家都知道健康碼的顏色有紅碼、綠碼、黃碼,近日湖南健康碼上線“藍(lán)碼”,不少小伙伴發(fā)現(xiàn)自己健康碼變藍(lán)了,都想趕緊恢復(fù)綠碼,那么藍(lán)碼怎么變綠碼需要幾天?下面小編為大家?guī)硭{(lán)碼變綠碼需要…

      2022年11月25日
    • 拼多多百億補貼預(yù)售一般多久發(fā)貨(拼多多百億補貼預(yù)售)

      拼多多里面有很多優(yōu)惠活動,其中百億補貼活動非?;鸨?,一些里面的東西價格比別的平臺便宜,質(zhì)量也有保障,還有預(yù)售的活動,那么拼多多百億補貼預(yù)售一般多久發(fā)貨?下面小編為大家?guī)砥炊喽喟賰|…

      2022年11月25日
    • 北京疫情多久能解除封控(北京疫情還要多久結(jié)束)

      最近一段時間北京疫情形勢備受關(guān)注,馬上就要到年底了,不少人想要去北京辦事,。都非常關(guān)注當(dāng)?shù)匾咔橄嚓P(guān)政策,那么 北京疫情多久能解除封控?北京疫情什么時候恢復(fù)正常生活?下面小編為大家?guī)А?/p>

      2022年11月25日
    • 客服的崗位職責(zé)怎么寫(客服工作內(nèi)容及職責(zé))

      各位小伙伴們大家周一好,又到了每周一給大家分享干貨內(nèi)容的時候啦~ 本期來跟大家分享一下客服工作管理流程以及客服崗位里面的每項職能崗位的核心細(xì)則,也是干貨滿滿推薦收藏~ 一.補償流程…

      2022年11月25日
    • cpu性能天梯圖2022 AMD CPU天梯圖最新排行榜出爐

      用戶在DIY自己的主機時選擇CPU是非常關(guān)鍵的,CPU可以說是電腦的大腦,大家也都想追求好一點的CPU來使用,但型號太多了,大部分的用戶都不知道目前哪一款CPU比較好用,快來看看詳…

      2022年11月24日
    • 《寶可夢朱紫》暴飛龍怎么抓?暴飛龍獲得方法

      寶可夢朱紫暴飛龍位置在哪?在游戲中,很多玩家還不清楚暴飛龍具體要怎么樣獲得,其實獲得方法很簡單,暴飛龍直接是沒得抓的,需要玩家從寶貝龍進(jìn)化得到,下面一起來看一下寶可夢朱紫暴飛龍獲得…

      2022年11月23日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息