mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-04-30 06:37:36 +00:00
160 lines
4.8 KiB
Java
160 lines
4.8 KiB
Java
package net.lamgc.cgj.bot;
|
|
|
|
import com.google.common.base.Throwables;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.util.*;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
/**
|
|
* 随机间隔发送器
|
|
*/
|
|
public class RandomIntervalSendTimer extends TimerTask {
|
|
|
|
private final static Timer timer = new Timer("Thread-RandomIntervalSendTimer", true);
|
|
private final static Logger log = LoggerFactory.getLogger(RandomIntervalSendTimer.class);
|
|
private final static Map<Long, RandomIntervalSendTimer> timerMap = new HashMap<>();
|
|
|
|
private final long timerId;
|
|
private final Random timeRandom = new Random();
|
|
private final AutoSender sender;
|
|
private final long time;
|
|
private final int floatTime;
|
|
private final AtomicBoolean loop = new AtomicBoolean();
|
|
private final AtomicBoolean start = new AtomicBoolean();
|
|
private final String hashId = Integer.toHexString(this.hashCode());
|
|
|
|
|
|
/**
|
|
* 创建一个随机延迟发送器
|
|
* @param timerId 该Timer的标识,
|
|
* 标识必须是唯一的, 当使用相同id创建时, 将会返回该id所属的Timer对象
|
|
* @param sender 自动发送器
|
|
* @param time 最低时间(ms)
|
|
* @param floatTime 浮动时间(ms)
|
|
* @param startNow 现在开始
|
|
* @param loop 是否循环
|
|
*/
|
|
public static RandomIntervalSendTimer createTimer(long timerId, AutoSender sender, long time, int floatTime, boolean startNow, boolean loop) {
|
|
if(timerMap.containsKey(timerId)) {
|
|
return timerMap.get(timerId);
|
|
}
|
|
|
|
RandomIntervalSendTimer timer = new RandomIntervalSendTimer(timerId, sender, time, floatTime, startNow, loop);
|
|
timerMap.put(timerId, timer);
|
|
return timer;
|
|
}
|
|
|
|
/**
|
|
* 通过Id获取Timer
|
|
* @param id 待获取Timer对应的Id
|
|
* @return 返回RandomIntervalSendTimer对象
|
|
* @throws NoSuchElementException 当不存在Timer时抛出
|
|
*/
|
|
public static RandomIntervalSendTimer getTimerById(long id) {
|
|
if(!timerMap.containsKey(id)) {
|
|
throw new NoSuchElementException("id=" + id);
|
|
}
|
|
return timerMap.get(id);
|
|
}
|
|
|
|
/**
|
|
* 获取所有id
|
|
* @return 所有TimerId的集合
|
|
*/
|
|
public static Set<Long> timerIdSet() {
|
|
return new HashSet<>(timerMap.keySet());
|
|
}
|
|
|
|
/**
|
|
* 创建一个随机延迟发送器
|
|
* @param timerId 该Timer的标识
|
|
* @param sender 自动发送器
|
|
* @param time 最低时间(ms)
|
|
* @param floatTime 浮动时间(ms)
|
|
* @param startNow 现在开始
|
|
* @param loop 是否循环
|
|
*/
|
|
private RandomIntervalSendTimer(
|
|
long timerId,
|
|
AutoSender sender,
|
|
long time,
|
|
int floatTime,
|
|
boolean startNow,
|
|
boolean loop) {
|
|
this.timerId = timerId;
|
|
this.sender = sender;
|
|
this.time = time;
|
|
this.floatTime = floatTime;
|
|
timerMap.put(timerId, this);
|
|
if(startNow) {
|
|
start(loop);
|
|
}
|
|
}
|
|
|
|
public void start() {
|
|
start(this.loop.get());
|
|
}
|
|
|
|
/**
|
|
* 启动定时器
|
|
* @param loop 是否循环, 如果为true, 则任务完成后会自动调用start方法继续循环, 直到被调用{@code #}或总定时器被销毁;
|
|
*/
|
|
public void start(boolean loop) {
|
|
this.loop.set(loop);
|
|
long nextDelay = time + (floatTime <= 0 ? 0 : timeRandom.nextInt(floatTime));
|
|
Date nextDate = new Date();
|
|
nextDate.setTime(nextDate.getTime() + nextDelay);
|
|
log.info("定时器 {} 下一延迟: {}ms ({})", hashId, nextDelay, nextDate);
|
|
if(start.get()) {
|
|
try {
|
|
Field state = this.getClass().getSuperclass().getDeclaredField("state");
|
|
state.setAccessible(true);
|
|
state.setInt(this, 0);
|
|
state.setAccessible(false);
|
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
e.printStackTrace();
|
|
return;
|
|
}
|
|
}
|
|
start.set(true);
|
|
timer.schedule(this, nextDelay);
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
sender.send();
|
|
} catch (Exception e) {
|
|
log.error("定时器 {} 执行时发生异常:\n{}",
|
|
Integer.toHexString(this.hashCode()),
|
|
Throwables.getStackTraceAsString(e));
|
|
}
|
|
if (this.loop.get()) {
|
|
start();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 取消该定时器
|
|
* @return 取消成功返回true
|
|
*/
|
|
@Override
|
|
public boolean cancel() {
|
|
start.set(false);
|
|
loop.set(false);
|
|
return super.cancel();
|
|
}
|
|
|
|
/**
|
|
* 销毁这个定时器
|
|
*/
|
|
public void destroy() {
|
|
cancel();
|
|
timerMap.remove(this.timerId);
|
|
}
|
|
|
|
}
|