
ScheduledThreadPoolExecutor實(shí)現(xiàn)ScheduledExecutorService接口實(shí)現(xiàn)了一些定時(shí)任務(wù)處理的方法。public interface ScheduledExecutorService extends ExecutorService { ScheduledFuture? schedule(Runnable var1, long var2, TimeUnit var4); V ScheduledFutureV schedule(CallableV var1, long var2, TimeUnit var4); ScheduledFuture? scheduleAtFixedRate(Runnable var1, long var2, long var4, TimeUnit var6); ScheduledFuture? scheduleWithFixedDelay(Runnable var1, long var2, long var4, TimeUnit var6); }scheduleRunnable ...一次性延遲任務(wù)。在delay時(shí)間后執(zhí)行一次Runnable不關(guān)心返回值返回ScheduledFuture?只能拿狀態(tài)/取消拿不到結(jié)果。schedule(CallableV...)同樣是一次性延遲但傳Callable而非Runnable執(zhí)行完有返回值ScheduledFutureV.get()能拿到計(jì)算結(jié)果。適合延遲后算點(diǎn)東西并返回的場(chǎng)景。scheduleAtFixedRate以period為間隔來(lái)觸發(fā)任務(wù)的每間隔period后檢查任務(wù)是否執(zhí)行完畢來(lái)決定是否立刻執(zhí)行下一次任務(wù)如果上一次任務(wù)沒(méi)執(zhí)行完則等待執(zhí)行完后立刻執(zhí)行下一次任務(wù)。即首次在initialDelay后執(zhí)行之后以上一次任務(wù)開(kāi)始時(shí)間為基準(zhǔn)每隔period觸發(fā)下一次。關(guān)鍵行為若某次任務(wù)執(zhí)行耗時(shí)超過(guò)period下一次會(huì)緊接著上一次結(jié)束后立即執(zhí)行不會(huì)并發(fā)重疊但頻率被拉長(zhǎng)。嚴(yán)格按開(kāi)始時(shí)間對(duì)齊理論周期恒定。例如period5s任務(wù)跑 2s → 0s 開(kāi)始、2s 結(jié)束、5s 又開(kāi)始若任務(wù)跑 8s → 0s 開(kāi)始、8s 結(jié)束、8s 又立即開(kāi)始被拖慢。實(shí)際應(yīng)用場(chǎng)景下如果任務(wù)執(zhí)行耗時(shí)小于period則相當(dāng)于每隔period時(shí)間觸發(fā)一次任務(wù)執(zhí)行但是如果任務(wù)執(zhí)行耗時(shí)大于period間隔本身則會(huì)連續(xù)不斷地執(zhí)行任務(wù)。任務(wù)觸發(fā)的間隔最小是period最大是任務(wù)執(zhí)行耗時(shí)耗時(shí)大于period時(shí)scheduleWithFixedDelay這個(gè)方法是在每次任務(wù)執(zhí)行完成后延遲delay時(shí)間后觸發(fā)下一次任務(wù)執(zhí)行。不管任務(wù)command執(zhí)行的時(shí)間是多長(zhǎng)下一次任務(wù)的執(zhí)行時(shí)間都是上一次任務(wù)執(zhí)行完后在等待延遲間隔delay時(shí)間后執(zhí)行下一次任務(wù)。即首次在initialDelay后執(zhí)行之后以上一次任務(wù)結(jié)束時(shí)間為基準(zhǔn)等待delay后再執(zhí)行下一次。關(guān)鍵行為無(wú)論任務(wù)跑多久兩次執(zhí)行之間永遠(yuǎn)間隔固定的delay結(jié)束 → 等 delay → 再開(kāi)始。周期 任務(wù)耗時(shí) delay不恒定。private ScheduledThreadPoolExecutor scheduledPool new ScheduledThreadPoolExecutor(1); //間隔60s執(zhí)行一次refreshToken方法 scheduledPool.scheduleAtFixedRate(() - this.refreshToken(),0, 60,TimeUnit.SECONDS);