0

我有一个队列实现。为了执行出队,我使用 poll() API 来移除头部,但它会抛出它不应该抛出的 NoSuchElementException。谁能解释我为什么会这样?我的队列有足够多的数据可以出队。

protected boolean enQueue(ByteBuffer data){
    if (queue.offer(data)){
        return true;
    }else {
        return false;
    }   
}

protected ByteBuffer deQueue(){
    ByteBuffer data = null;
    try{
        if(getQueueCount() > 0)
        {
            data = queue.poll();
            if(data != null){
                return data;
            }else {
                return null;
            }
        }
        else{
            return null;
        }
    }
    catch(NoSuchElementException e){
        e.printStackTrace();
        return null;
    }
}

编辑:

java.util.Queue<ByteBuffer> queue;

public Queue(){
    queue = new LinkedList<ByteBuffer>();
}
protected int getQueueCount(){
    return queue.size();
}

堆栈跟踪:

03-04 14:58:50.205: W/System.err(7937): java.util.NoSuchElementException 03-04 14:58:50.205: W/System.err(7937): 在 java.util.LinkedList.removeFirstImpl( LinkedList.java:689) 03-04 14:58:50.205: W/System.err(7937): 在 java.util.LinkedList.removeFirst(LinkedList.java:676) 03-04 14:58:50.205: W/ System.err(7937): at java.util.LinkedList.poll(LinkedList.java:895) 03-04 14:58:50.205: W/System.err(7937): at com.android.testapp.Queue.deQueue (Queue.java:37) 03-04 14:58:50.205: W/System.err(7937): 在 com.android.testapp.DisplayData.run(LogViewActivity.java:1164)

编辑2:

排队

Queue.getInstance().enQueue(tempByteBufRead);

我用它来将通过蓝牙接收到的数据排入 bluetooth.class。tempByteBufRead 是一个字节缓冲区。这是在一个单独的线程中完成的。

出队

while( Queue.getInstance().getQueueCount() <= 0);


        try {
            if(LLTestAppActivity.DEBUG){
                Log.d("DisplayData", "Crossed queue count...");
            }
            ByteBuffer tempByteBuf = Queue.getInstance().deQueue(); 
            if(null == tempByteBuf){
                Log.d("DisplayData", "No data in queue...");
            }
            else{
                   //TODO:
                 }
            }catch(){}

这就是我出列的方式。这是在不同的类文件中。这是另一个用于在文本视图上显示数据的线程。

4

2 回答 2

2

您的队列是空的(或者更确切地说,缺少它的第一个元素)。LinkedList 中的 poll 方法是这样实现的:

public E poll() {
    if (size==0)
        return null;
    return removeFirst();
}

removeFirst 是一个会抛出 NoSuchElementException 的方法。

您应该尝试找出导致第一个元素丢失的原因,因为显然您的队列报告了非零数量的元素。如何将对象推送到队列中?

编辑:看到您的编辑后建议对您的代码进行更改:

// use a thread-safe queue implementation:
java.util.concurrent.BlockingQueue<ByteBuffer> queue;

// make the constructor private, since it's a singleton you don't want anyone else to be able to instantiate
private Queue() {
    queue = new LinkedBlockingQueue<ByteBuffer>();
}

// enQueue and deQueue without a bunch of redundant code:
protected boolean enQueue(ByteBuffer data) {
    return queue.offer(data);
}

protected ByteBuffer deQueue() {
    return queue.take();
}

// enqueue data like this:
Queue.getInstance().enQueue(tempByteBufRead);

// and dequeue it:
try {
    ByteBuffer tempButeBuf = Queue.getInstance().deQueue();
    // TODO: do something useful with the buffer
} catch (InterruptedException e) {
}
于 2014-03-04T10:01:25.107 回答
0

窥视:

检索但不删除此队列的头部,如果此队列为空,则返回 null。返回:此队列的头部,如果此队列为空,则返回 null

轮询:

检索并删除此队列的头部,如果此队列为空,则返回 null。返回:此队列的头部,如果此队列为空,则返回 null

因此,您可以使用 peek 方法。而且您的问题中的问题是队列是空的,因此请确保您正确地将数据排队

于 2014-03-04T09:18:23.250 回答