@Data
public class ItemDelayed implements Delayed {
private Long id;
//触发时间
private long time;
//内容
private String body;
public ItemDelayed(){
}
public ItemDelayed(Long id,long time,String body, TimeUnit unit) {
this.id = id;
this.body = body;
this.time = TimeUnit.NANOSECONDS.convert(time, TimeUnit.MILLISECONDS) + System.nanoTime();
}
@Override
public long getDelay(TimeUnit unit) {
return time - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed o) {
ItemDelayed item = (ItemDelayed) o;
long diff = this.time - item.time;
if (diff <= 0) {
return -1;
}else {
return 1;
}
}
}
@Slf4j
public class BroadcastThread implements Runnable{
private DelayQueue<ItemDelayed> delayQueue;
@Autowired(required = false)
private BroadcastMapper broadcastMapper;
/**
* 封装queue
* @param id 任务ID
* @param duration 时长(天)
* @param body 标题
* @return
*/
public BroadcastThread(Long id,Integer duration,String body){
this.delayQueue = new DelayQueue();
ItemDelayed item = new ItemDelayed();
item.setId(id);
item.setBody(body);
Long exeTime = CommonTypeSwitch.getTimestampOfDateTime(LocalDateTime.now().plusDays(duration));
item.setTime(exeTime);
this.delayQueue.offer(item);
}
public BroadcastThread(DelayQueue<ItemDelayed> delayQueue){
this.delayQueue = delayQueue;
}
@Override
public void run() {
while (true) {
try {
ItemDelayed take = delayQueue.take();
log.info("消费消息id:" + take.getId()+ " 消息体:" + take.getBody());
//道具服务时间过期,修改广播列表 该任务等广播状态置为失效
Broadcast entity = broadcastMapper.queryByTaskId(take.getId(),StatusEnum.BroadcastStatus.PROCESSING.getCode(),
StatusEnum.DflagStatus.VALID.getCode());
if (null != entity){
Broadcast record = new Broadcast();
record.setStatus(StatusEnum.BroadcastStatus.OVER.getCode());
record.setId(entity.getId());
record.setUpdateTime(new Date());
record.setUpdateBy(ConstantValue.L_ZERO);
broadcastMapper.updateByPrimaryKeySelective(record);
}
} catch (InterruptedException e) {
log.error("error:",e);
}
}
}
}
如果发生断电情况,导致数据丢失,可以加上数据库,把需要发到延时队列到数据都存到数据库+版本(防止重复消费),每次重启项目扫描数据填充到队列里,删除数据库失败的不进行业务处理,或者先业务处理,删除失败回滚业务(业务也要有版本,防止重复操作)
本文介绍了一个Java类,实现ItemDelayed,用于在指定时间后执行任务,并讨论了如何通过BroadcastThread使用DelayQueue进行任务调度,同时考虑了断电情况下数据持久化策略。
3711





