队列上的NoSuchElementException

时间:2014-07-02 09:24:35

标签: java android multithreading exception nosuchelementexception

我在Java中遇到Queue的问题。它声明如下:

Queue<MotionEvent> touchQueue = new LinkedList<MotionEvent>();

我只在一个地方添加元素(但在回调中,很可能是从一个线程调用的):

@Override 
public boolean onTouchEvent(MotionEvent me) {
    touchQueue.add(me);
    return true;
}

我通过调用Thread函数来消费主synchronized上的事件:

public synchronized void UpdateTouches() {
    while(!touchQueue.isEmpty()) {
        try {
            MotionEvent me = touchQueue.poll();
            ProcessTouchEvent(me);
        } catch (NoSuchElementException e) {
            return;
        }
    }
}

问题在于,有时轮询会在NoSuchElementException上升,之后所有后续轮询调用都会提升Exception

任何人都知道原因可能是什么?或者有没有办法在不再获取Exception的情况下删除头部对象?

请注意size()返回&gt;发生Exception时为0,

谢谢, / C

修改

这是callstack:

FATAL EXCEPTION: GLThread 302 java.util.NoSuchElementException
    at java.util.LinkedList.removeFirstImpl(LinkedList.java:689)
    at java.util.LinkedList.remove(LinkedList.java:899)
    at com.xxxxx.GG.GGActivity.UpdateTouches(GGActivity.java:718)
    at com.xxxxx.GG.GGView$Renderer.onDrawFrame(GGView.java:414)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
Force finishing activity

以下是生成日志的函数的最新版本:

public synchronized void UpdateTouches()
{
    //System.out.println("Got touch event" + touchQueue.size());
    while(!touchQueue.isEmpty())
    {
        try {
            MotionEvent me = touchQueue.poll();
            ProcessTouchEvent(me);
        } catch (NoSuchElementException e)
        {
            touchQueue.remove();
            return;
        }

    }
}

1 个答案:

答案 0 :(得分:1)

当你已经知道队列为空时调用remove()没有任何意义。并且在不抛出它的方法上捕获NoSuchElementException,同上。只需删除所有代码即可。

但是你的代码不是线程安全的。调用add()的方法需要在队列上同步,并且调用isEmpty()和poll()的方法同上,并且它应该在队列为空时等待队列。

或者使用java.util.concurrent队列。