在使用优先级队列
PriorityBlockingQueue 时发现当出现相同优先级时,出队的顺序就和入队不相同
其根本原因是。。。
解决方法:
定义一个包装类,依赖第二种属性来排序相同优先级
package com.jwuwb.kids.stream;
import java.util.concurrent.atomic.AtomicLong;
/**
* <E extends Comparable> 上限通配符指定接收Comparable 接口。
* <? super E> 下限通配符,接收必须是E的父类。
* <E extends Comparable<? super E>> 合起来表示接受实现了Comparable接口并且可以和其父类进行比较的类型E及其父类型。
*
* @param <E>
*/
public class PackageEntry<E extends Comparable<? super E>> implements Comparable<PackageEntry<E>> {
static final AtomicLong seq = new AtomicLong(0);
final long seqNum;
final E entry;
public PackageEntry(E entry) {
seqNum = seq.getAndIncrement();
this.entry = entry;
}
public E getEntry() {
return entry;
}
public int compareTo(PackageEntry<E> other) {
int res = entry.compareTo(other.entry);
if (res == 0 && other.entry != this.entry)
res = (seqNum < other.seqNum ? -1 : 1);
return res;
}
@Override
public String toString() {
return "PackageEntry{" +
"seqNum=" + seqNum +
", entry=" + entry +
'}';
}
}
使用的话:
import com.google.common.collect.Maps;
import com.jwuwb.kids.stream.quartz.CronUtil;
import com.jwuwb.kids.stream.quartz.JobAndTriggerService;
import com.jwuwb.kids.utils.DateTimeUtil;
import com.jwuwb.kids.utils.UUIDUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.PriorityBlockingQueue;
/**
* @program: kids
* @description: 告警事件视频优先级队列
* @author: zf
* @create: 2021-03-03 17:39
**/
@Getter
@Setter
@Service
public class WarnPriorityQueue implements Comparable<WarnPriorityQueue>{
@Autowired
private JobAndTriggerService jobAndTriggerService;
private String msg;
private Integer order;
private String uid;
private String tag;
public WarnPriorityQueue() {
}
public WarnPriorityQueue(String msg, Integer order, String uid, String tag) {
this.msg = msg;
this.order = order;
this.uid = uid;
this.tag = tag;
}
public WarnPriorityQueue(String msg, Integer order, String tag) {
this.msg = msg;
this.order = order;
this.uid = UUIDUtil.getUUIDStringWithNoHyphen();
this.tag = tag;
}
@Override
public int compareTo(WarnPriorityQueue o) {
return this.order.compareTo(o.order);
}
/**
* 优先级队列
*/
public static final PriorityBlockingQueue<FifoEntry> priorityQueue =
new PriorityBlockingQueue<>(11);
public static void main(String[] args) throws InterruptedException {
WarnPriorityQueue warnPriorityQueue = new WarnPriorityQueue();
warnPriorityQueue.setMsg("1号");
warnPriorityQueue.setOrder(2);
warnPriorityQueue.setUid(UUIDUtil.getUUIDStringWithNoHyphen());
WarnPriorityQueue warnPriorityQueue2 = new WarnPriorityQueue();
warnPriorityQueue2.setMsg("2号");
warnPriorityQueue2.setOrder(2);
warnPriorityQueue2.setUid(UUIDUtil.getUUIDStringWithNoHyphen());
WarnPriorityQueue warnPriorityQueue3 = new WarnPriorityQueue();
warnPriorityQueue3.setMsg("3号");
warnPriorityQueue3.setOrder(1);
warnPriorityQueue3.setUid(UUIDUtil.getUUIDStringWithNoHyphen());
WarnPriorityQueue warnPriorityQueue4 = new WarnPriorityQueue();
warnPriorityQueue4.setMsg("4号");
warnPriorityQueue4.setOrder(1);
warnPriorityQueue4.setUid(UUIDUtil.getUUIDStringWithNoHyphen());
priorityQueue.put(new FifoEntry<>(warnPriorityQueue));
priorityQueue.put(new FifoEntry<>(warnPriorityQueue2));
priorityQueue.put(new FifoEntry<>(warnPriorityQueue3));
priorityQueue.put(new FifoEntry<>(warnPriorityQueue4));
for (int i = 0; i < 4; i++) {
WarnPriorityQueue entry = (WarnPriorityQueue) priorityQueue.take().entry;
System.out.println(entry.getMsg());
}
}
}