All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.cron.TaskTable Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.cron;

import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.pattern.CronPattern;
import cn.hutool.cron.task.CronTask;
import cn.hutool.cron.task.Task;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 定时任务表
* 任务表将ID、表达式、任务一一对应,定时任务执行过程中,会周期性检查定时任务表中的所有任务表达式匹配情况,从而执行其对应的任务
* 任务的添加、移除使用读写锁保证线程安全性 * * @author Looly */ public class TaskTable implements Serializable { private static final long serialVersionUID = 1L; public static final int DEFAULT_CAPACITY = 10; private final ReadWriteLock lock; private final List ids; private final List patterns; private final List tasks; private int size; /** * 构造 */ public TaskTable() { this(DEFAULT_CAPACITY); } /** * 构造 * * @param initialCapacity 容量,即预估的最大任务数 */ public TaskTable(int initialCapacity) { lock = new ReentrantReadWriteLock(); ids = new ArrayList<>(initialCapacity); patterns = new ArrayList<>(initialCapacity); tasks = new ArrayList<>(initialCapacity); } /** * 新增Task * * @param id ID * @param pattern {@link CronPattern} * @param task {@link Task} * @return this */ public TaskTable add(String id, CronPattern pattern, Task task) { final Lock writeLock = lock.writeLock(); writeLock.lock(); try { if (ids.contains(id)) { throw new CronException("Id [{}] has been existed!", id); } ids.add(id); patterns.add(pattern); tasks.add(task); size++; } finally { writeLock.unlock(); } return this; } /** * 获取所有ID,返回不可变列表,即列表不可修改 * * @return ID列表 * @since 4.6.7 */ public List getIds() { final Lock readLock = lock.readLock(); readLock.lock(); try { return Collections.unmodifiableList(this.ids); } finally { readLock.unlock(); } } /** * 获取所有定时任务表达式,返回不可变列表,即列表不可修改 * * @return 定时任务表达式列表 * @since 4.6.7 */ public List getPatterns() { final Lock readLock = lock.readLock(); readLock.lock(); try { return Collections.unmodifiableList(this.patterns); } finally { readLock.unlock(); } } /** * 获取所有定时任务,返回不可变列表,即列表不可修改 * * @return 定时任务列表 * @since 4.6.7 */ public List getTasks() { final Lock readLock = lock.readLock(); readLock.lock(); try { return Collections.unmodifiableList(this.tasks); } finally { readLock.unlock(); } } /** * 移除Task * * @param id Task的ID * @return 是否成功移除,{@code false}表示未找到对应ID的任务 */ public boolean remove(String id) { final Lock writeLock = lock.writeLock(); writeLock.lock(); try { final int index = ids.indexOf(id); if (index < 0) { return false; } tasks.remove(index); patterns.remove(index); ids.remove(index); size--; } finally { writeLock.unlock(); } return true; } /** * 更新某个Task的定时规则 * * @param id Task的ID * @param pattern 新的表达式 * @return 是否更新成功,如果id对应的规则不存在则不更新 * @since 4.0.10 */ public boolean updatePattern(String id, CronPattern pattern) { final Lock writeLock = lock.writeLock(); writeLock.lock(); try { final int index = ids.indexOf(id); if (index > -1) { patterns.set(index, pattern); return true; } } finally { writeLock.unlock(); } return false; } /** * 获得指定位置的{@link Task} * * @param index 位置 * @return {@link Task} * @since 3.1.1 */ public Task getTask(int index) { final Lock readLock = lock.readLock(); readLock.lock(); try { return tasks.get(index); } finally { readLock.unlock(); } } /** * 获得指定id的{@link Task} * * @param id ID * @return {@link Task} * @since 3.1.1 */ public Task getTask(String id) { final int index = ids.indexOf(id); if (index > -1) { return getTask(index); } return null; } /** * 获得指定位置的{@link CronPattern} * * @param index 位置 * @return {@link CronPattern} * @since 3.1.1 */ public CronPattern getPattern(int index) { final Lock readLock = lock.readLock(); readLock.lock(); try { return patterns.get(index); } finally { readLock.unlock(); } } /** * 任务表大小,加入的任务数 * * @return 任务表大小,加入的任务数 * @since 4.0.2 */ public int size() { return this.size; } /** * 任务表是否为空 * * @return true为空 * @since 4.0.2 */ public boolean isEmpty() { return this.size < 1; } /** * 获得指定id的{@link CronPattern} * * @param id ID * @return {@link CronPattern} * @since 3.1.1 */ public CronPattern getPattern(String id) { final int index = ids.indexOf(id); if (index > -1) { return getPattern(index); } return null; } /** * 如果时间匹配则执行相应的Task,带读锁 * * @param scheduler {@link Scheduler} * @param millis 时间毫秒 */ public void executeTaskIfMatch(Scheduler scheduler, long millis) { final Lock readLock = lock.readLock(); readLock.lock(); try { executeTaskIfMatchInternal(scheduler, millis); } finally { readLock.unlock(); } } @Override public String toString() { final StringBuilder builder = StrUtil.builder(); for (int i = 0; i < size; i++) { builder.append(StrUtil.format("[{}] [{}] [{}]\n", ids.get(i), patterns.get(i), tasks.get(i))); } return builder.toString(); } /** * 如果时间匹配则执行相应的Task,无锁 * * @param scheduler {@link Scheduler} * @param millis 时间毫秒 * @since 3.1.1 */ protected void executeTaskIfMatchInternal(Scheduler scheduler, long millis) { for (int i = 0; i < size; i++) { if (patterns.get(i).match(scheduler.config.timezone, millis, scheduler.config.matchSecond)) { scheduler.taskExecutorManager.spawnExecutor(new CronTask(ids.get(i), patterns.get(i), tasks.get(i))); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy