延迟队列使用时,相当于在开启一个新的线程,在没有到达指定时间时,这个线程会一直阻塞,直到到了指定时间,队列会释放当前的数据,并继续阻塞到下一个数据
@Component
public class DelayedMessageUtils implements ApplicationRunner {
//在容器启动时自动执行
private volatile boolean interrupt;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
private static Logger logger = LoggerFactory.getLogger(DelayedMessageUtils.class);
@Override
public void run(ApplicationArguments args) throws UnknownHostException, InterruptedException {
DelayQueue<DelayedMessage> delayQueue = ConstConfig.delayQueue;
List<NoticeInfo> list = noticeService.getDelayMsgList();
list.stream().forEach(e -> {
DelayedMessage delayedMessage = new DelayedMessage(e.getId(), e.getTiming().getTime());
delayQueue.offer(delayedMessage);
});
/**
ConstConfig.delayQueue.put(DelayedMessage)
* 第一步
* spring启动的时候去数据库拿定时发送且没有发送的数据添加到delayQueue
* ConstConfig.delayQueue.put(DelayedMessage)
* 注意这里的数据获取要跟ip来获取,以前是哪个ip添加的数据要用这个ip来发送,避免重复发送
* 待实现....
*/
threadPoolExecutor.execute(new Runnable() {
@SneakyThrows
@Override
public void run() {
while (interrupt == false) {
DelayedMessage delayedMessage = ConstConfig.delayQueue.take();
//拿到delayedMessage.getDataId()去数据库查询待发送的数据 执行业务操作...
Boolean bool = noticeService.sendTiming(delayedMessage.getDataId());
if(bool==false){
//发送给管理员
noticeService.sendAdmin(delayedMessage.getDataId());
}
}
}
});
}
@Component
public class Destroy implements DisposableBean {
@Override
public void destroy() throws Exception {
interrupt = true;
threadPoolExecutor.shutdown();
}
}
}
package com.cantaline.noticecenter.vo.delayed;
import lombok.SneakyThrows;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class DelayedMessage implements Delayed {
/**
* 数据要发送的数据id
*/
private Long dataId;
/**
* 定时发送的时间戳 毫秒
*/
private Long sendTime;
//
public Long getDataId() {
return this.dataId;
}
public Long getSendTime() {
return this.sendTime;
}
public DelayedMessage(Long m, Long time) {
this.dataId = m;
this.sendTime = time;
}
@SneakyThrows
@Override
public long getDelay(TimeUnit unit) {
return sendTime - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed o) {
DelayedMessage item = (DelayedMessage) o;
long diff = this.sendTime - item.sendTime;
if (diff > 0) {
return 1;
}
return -1;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (getClass() != o.getClass()) {
return false;
}
DelayedMessage other = (DelayedMessage) o;
if (!dataId.equals(other.dataId)) {
return false;
}
return true;
}
}