3

我在使用QueueJava 时遇到了一些问题。它声明如下:

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;
        }
    }
}

问题是有时 poll 会上升 a NoSuchElementException,然后所有后续的 poll 调用都会引发 that Exception

任何人都知道可能是什么原因?或者有什么方法可以在不Exception重新获得头部对象的情况下移除头部对象?

请注意,发生size()时返回 > 0 Exception

谢谢,/ C。

编辑:

这是调用堆栈:

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;
        }

    }
}
4

1 回答 1

1

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

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

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

于 2014-07-03T01:48:25.783 回答