3

私はQueueJavaでいくつかの問題を抱えています。次のように宣言されています。

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

要素を 1 か所に追加するだけです (ただし、コールバックでは、スレッドから呼び出される可能性が最も高い):

@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 が aNoSuchElementExceptionを上げ、その後のすべての poll 呼び出しでそれが上がることがあるということです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 に答える