Cha*_*hap 7 java priority-queue fifo
我正在尝试在Java中创建一个优先级阻塞队列,该队列维护具有相同优先级的元素的FIFO顺序.Oracle文档提供了一些帮助,但我仍然非常纠结.
我应该注意以下主题对我来说都是非常新的:泛型,作为类型的接口和静态嵌套类.所有这些都在以下类定义中发挥作用.特别是泛型,令人困惑,我确信我已经完全搞砸了他们.
我已经包含了注释,以确定我目前正在获得的编译器错误.
几个具体问题:
是否可以让类表示排队的事件对象,实际的队列是静态类成员?
将Oracle的FIFO事件"包装器"作为静态嵌套类包含在内是否合理?
我在这里至少走在正确的轨道上,在一个外层阶段做到这一切吗?
这是我写的课程:
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
public class FIFOPBQEvent {
/**
* First we define a static nested class which, when instantiated,
* encapsulates the "guts" of the event - a FIFOPBQEvent - along with
* a sequence number that assures FIFO behavior of events of like priority.
*
* The following is lifted ALMOST verbatim (I added "static" and some
* comments) from Oracle documentation on adding FIFO-ness to a Priority
* Blocking Queue:
* http://download.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html
* As the Oracle doc points out:
*
* "A static nested class interacts with the instance members of its outer
* class (and other classes) just like any other top-level class. In
* effect, a static nested class is behaviorally a top-level class that
* has been nested in another top-level class for packaging convenience."
*
*/
static class FIFOEntry<E extends Comparable<? super E>> implements
Comparable<FIFOEntry<E>> {
final static AtomicLong seq = new AtomicLong();
final long seqNum; // instance
final E entry;
public FIFOEntry(E entry) {
seqNum = seq.getAndIncrement();
this.entry = entry;
}
public E getEntry() {
return entry;
}
/** Here is implementation of Comparable */
public int compareTo(FIFOEntry<E> other) {
int res = entry.compareTo(other.entry);
if (res == 0 && other.entry != this.entry)
res = (seqNum < other.seqNum ? -1 : 1);
return res;
}
}
/**
* Now we declare a single (static) PBQ of FIFO entries into which
* PBQFIFOEvents will be added and removed.
*/
/** FLAGGED AS ERROR BY COMPILER */
// Bound mismatch: The type FIFOPBQEvent is not a valid substitute for the
// bounded parameter <E extends Comparable<? super E>> of the type
// FIFOPBQEvent.FIFOEntry<E>
private static PriorityBlockingQueue<FIFOEntry<FIFOPBQEvent>> theQueue =
PriorityBlockingQueue<FIFOEntry<FIFOPBQEvent>>();
/**
* And here are the "guts" of our event: the i.d. and state of the GUI widget
*/
private ConsoleObject obj = ConsoleObject.UNDEFINED_OBJ; // widget that was affected
private ObjectState state = ObjectState.UNDEFINED_STATE; // the widget's new state
/**
* Constructor specifying the class variables
*/
public FIFOPBQEvent(ConsoleObject theObj, ObjectState theState) {
obj = theObj;
state = theState;
}
/**
* Event queuing ("sending") and dequeuing ("receiving")
*/
public void sendEvent() {
/** FLAGGED AS ERROR BY COMPILER */
// The method put(FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>) in the type
// PriorityBlockingQueue<FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>> is not
// applicable for the arguments (FIFOPBQEvent)
theQueue.put(this);
}
public static FIFOPBQEvent receiveEvent() {
/** FLAGGED AS ERROR BY COMPILER */
// Type mismatch: cannot convert from FIFOPBQEvent.FIFOEntry<FIFOPBQEvent>
// to FIFOPBQEvent
FIFOPBQEvent event = theQueue.take();
return event;
}
/**
* ConsoleEvent accessors
*/
public ConsoleObject getObj() {
return this.obj;
}
public ObjectState getState() {
return this.state;
}
/**
* And for the first time, enums instead of public static final ints.
*/
public enum ConsoleObject {
UNDEFINED_OBJ,
RESERVED,
/** Console keys */
RESET,
DISPLAY_MAR,
SAVE,
INSERT,
RELEASE,
START,
SIE,
SCE,
/** Console toggle switches */
POWER,
PARITY_CHECK,
IO_CHECK,
OVERFLOW_CHECK,
SENSE_SWITCH_1,
SENSE_SWITCH_2,
SENSE_SWITCH_3,
SENSE_SWITCH_4
}
public enum ObjectState {
UNDEFINED_STATE,
/** Toggle switches */
OFF,
ON,
/** Console keys */
PRESSED,
}
}
Run Code Online (Sandbox Code Playgroud)
第一个错误是更严重的错误。发生这种情况是因为该类FIFOPBQEvent没有实现Comparable,它必须被视为FIFOEntry嵌套类的泛型类型。这是因为你限制E和说出来的extends Comparable<...>。基本上,您的FIFOPBQEvent类必须具有可比性才能提供队列的优先级(大概基于事件类型)。
要修复该错误,您需要:
将类的标题更改为:
public class FIFOPBQEvent implements Comparable<FIFOPBQEvent> {
Run Code Online (Sandbox Code Playgroud)在类中添加一个compareTo方法FIFOPBQEvent;就像是:
public int compareTo (FIFOPBQEvent other) {
// TODO - compare this and other for priority
return 0;
}
Run Code Online (Sandbox Code Playgroud)然后您需要将您的条目包装在您的sendEvent方法中:
public void sendEvent () {
theQueue.put(new FIFOEntry<FIFOPBQEvent> (this));
}
Run Code Online (Sandbox Code Playgroud)
最后一个小错误是您没有解开对象FIFOEntry。要解决此问题,请更改receiveEvent为:
public static FIFOPBQEvent receiveEvent () {
FIFOPBQEvent event = theQueue.take ().getEntry ();
return event;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5676 次 |
| 最近记录: |