今天看hutool工具中的TimedCache 時好奇他的緩存機制及定時清除原理 便簡單的看了一下他的源碼,總結出是
Map(緩存數據)+ScheduledExecutorService(定時清除緩存),其中的定時任務感覺比較有意思,則拷貝出來
public enum GlobalPruneTimer { /** * 單例對象 */ INSTANCE; /** * 緩存任務計數 */ private final AtomicInteger cacheTaskNumber = new AtomicInteger(1); /** * 定時器 */ private ScheduledExecutorService pruneTimer; /** * 構造 */ GlobalPruneTimer() { create(); } /** * 啟動定時任務 * * @param task 任務 * @param delay 周期 * @param unit * @return {@link ScheduledFuture}對象,可手動取消此任務 */ public ScheduledFuture<?> schedule(Runnable task, int delay, TimeUnit unit) { return this.pruneTimer.scheduleAtFixedRate(task, delay, delay, unit); } /** * 創建定時器 */ public void create() { if (null != pruneTimer) { shutdownNow(); } this.pruneTimer = new ScheduledThreadPoolExecutor(1, r -> ThreadUtil.newThread(r, StrUtil.format("Pure-Timer-{}", cacheTaskNumber.getAndIncrement()))); } /** * 銷毀全局定時器 */ public void shutdown() { if (null != pruneTimer) { pruneTimer.shutdown(); } } /** * 銷毀全局定時器 * * @return 銷毀時未被執行的任務列表 */ public List<Runnable> shutdownNow() { if (null != pruneTimer) { return pruneTimer.shutdownNow(); } return null; } }
使用例子:
public class ScheduleTest { public static void main(String[] args) { ScheduleTest test = new ScheduleTest(); GlobalPruneTimer.INSTANCE.schedule(test::schedule,5, SECONDS); } @SneakyThrows public void schedule(){ System.out.println("Start: " + DateUtil.now()); SECONDS.sleep(3); System.out.println("End : " + DateUtil.now()); } }