具体思路:
在容器初始化的时候就创建出一个 延迟队列 然后项目启动后随即启动一个线程一直监听这个队列
手动调用接口往队列中添加任务
依赖
一个最简单的web的应用即可
项目文件结构
第一步:在项目启动的时候就创建出一个延迟队列
@Configuration
public class DelayQueueConfig {
@Bean
public DelayQueue delayQueue() {
return new DelayQueue();
}
}
第二步:项目启动后开启一个线程去监听这个队列
/*ApplicationRunner的作用--项目启动后就执行run方法*/
@Component
public class BlockingQueueConsumer implements ApplicationRunner {
@Autowired
private DelayQueue delayQueue;
@Override
public void run(ApplicationArguments args) {
/*开启一个线程 去监听 delayQueue*/
new Thread(() -> {
while (true) {
try {
Order order = (Order) delayQueue.take();
order.run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
当然,还需要创建出一个能放进队列的类
public class Order implements Delayed {
private String orderNo;
private long time;
public Order(String orderNo, long time) {
this.orderNo = orderNo;
this.time = time;
}
@Override/*getDelay--获取现在还有多久才会被消费*/
public long getDelay(TimeUnit unit) {
return time - System.currentTimeMillis();
}
@Override/*决定队列中的顺序,谁在前 谁在后*/
public int compareTo(Delayed o) {
Order order = (Order) o;
return Long.compare(this.time, order.time);
}
public void run() {
System.out.println("订单号:" + orderNo + "已经被消费");
}
}
最后,我们可以随时调用接口添加任务
@RestController
@RequestMapping("/blockingQueue")
public class BlockingQueueController {
@Autowired
private DelayQueue delayQueue;
@GetMapping("/test")
public String test() {
return "success";
}
@GetMapping("/add")
public String add() {
Order order = new Order("1", 3000+System.currentTimeMillis());
Order order1 = new Order("2", 5000 + System.currentTimeMillis());
Order order2 = new Order("3", 1000 + System.currentTimeMillis());
delayQueue.put(order);
delayQueue.put(order1);
delayQueue.put(order2);
return "success";
}
}
结果