1.创建延时队列中的实体类,实现Delayed接口,重写其中的两个方法
@Data
public class BiddingInfoDto extends BiddingInfoEntity implements Delayed {
private long delayTime; //延迟时间
private BiddingInfoEntity biddingInfoEntity; //当前类包含这个类中的属性 bidName等
//参数是父类+延时时间(s)
public BiddingInfoDto(BiddingInfoEntity biddingInfoEntity,Long delayTime) {
this.biddingInfoEntity =biddingInfoEntity;
this.delayTime = System.currentTimeMillis()+ delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
return delayTime - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed o) {
BiddingInfoDto biddingInfoDto = (BiddingInfoDto)o;
long diff = this.delayTime - biddingInfoDto.delayTime;
if (diff <= 0) {// 改成>=会造成问题
return -1;
}else {
return 1;
}
}
}
2.创建线程类,此线程主要是为了能够监控延时队列的数据变化和拿出队列中的数据使用
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.concurrent.DelayQueue;
/**
* 延时队列使用类
*/
@Component
@Data
public class DelayQueueIoc implements Runnable {
public static DelayQueue<BiddingInfoDto> biddingInfoDtoDelayQueue = new DelayQueue<>();
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
while (!biddingInfoDtoDelayQueue.isEmpty()){
try {
//在延时队列中拿出已经到期的实体类
BiddingInfoDto biddingInfoDto = biddingInfoDtoDelayQueue.take();
System.out.println(new Date());
System.out.println(biddingInfoDto.getBiddingInfoEntity().getBiddingName()+"招标开始!");
System.out.println("延迟队列长度::"+biddingInfoDtoDelayQueue.size());
//websocket发送消息
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("出问题了!");
}
}
}
}
3.具体业务逻辑(向延时队列中添加实体数据)
//注入第二步类
@Autowired
DelayQueueIoc delayQueueIoc;
@RequestMapping("/save")
@RequiresPermissions("biddingInfo:biddinginfo:save")
public R save(@RequestBody BiddingInfoEntity biddingInfo) throws InterruptedException {
biddingInfo.setCreateTime(new Date());
//延迟时间 = (发布时间 - 当前时间) / 1000;(秒)
Long delayTime = ((biddingInfo.getStartTime().getTime()) - System.currentTimeMillis());
BiddingInfoDto biddingInfoDto = new BiddingInfoDto(biddingInfo,delayTime);
//加入延时队列
delayQueueIoc.biddingInfoDtoDelayQueue.add(biddingInfoDto);
System.out.println("加入延时队列!!!!在"+(delayTime/1000)+"秒后触发");
System.out.println(new Date());
System.out.println("延时队列长度:"+delayQueueIoc.biddingInfoDtoDelayQueue.size());
//执行线程 当前线程阻塞等待
Thread thread = new Thread(new DelayQueueIoc());
thread.start();
biddingInfoService.save(biddingInfo);
return R.ok();
}