0

私はOpenGLプログラミングにかなり慣れていないので、図面を単純化するための単純なエンジンを作成しました。ここで、加速度計に基づいて変換を行いたいのですが、ConcurrentModificationExceptionが発生します。

オブジェクトクラスは次のとおりです。

public class IbnRushdObject
{
    /** The graphical object to show */
    private Mesh mesh = null;

    /** List of transformations to be executed upon this object */
    private List<IbnRushdTransformation> transformations;

    /** Lock to prevent modification of the list when executing the transformations and viceversa */
    private final ReentrantLock lock = new ReentrantLock();

    /**
     * Initializes this IbnRushd object with a mesh
     * @param mesh
     */
    public IbnRushdObject(Mesh mesh)
    {
        this.mesh = mesh;
    }

    /**
     * Adds a transformation to be performed on this object<br>
     * The transformation does not take place until {@link #moveDraw(GL10)} is called
     * @param trans
     */
    public void addTransformation(IbnRushdTransformation trans)
    {
        try
        {
            lock.lock();
            if (transformations == null)
            {
                transformations = new LinkedList<IbnRushdTransformation>();         
            }
            transformations.add(trans);
        }
        finally
        {
            lock.unlock();
        }
    }

    /**
     * Executes transformations for this object and draws it
     * @param gl
     */
    public void moveDraw(GL10 gl)
    {
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();

        try
        {
            lock.lock();
            for(IbnRushdTransformation trans: transformations) // ConcurrentMoificationException thrown here
            {
                trans.execute(gl);
                if (!trans.isPermanent())
                {
                    transformations.remove(trans);
                }
            }
        }
        finally
        {
            lock.unlock();
        }

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        mesh.draw(gl);
    }
}

そして、moveDraw()メソッドはからのみ呼び出されます

@Override
public void onDrawFrame(GL10 gl)
{
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glClearColor(0, 0.5f, 0.5f, 1.0f);

    for(IbnRushdObject object : objectQueue)
    {
        object.moveDraw(gl);
    }
}

これは、描画されるすべてのオブジェクトのリストを保持します。

これは、加速度計のイベントをリッスンするコードです。リスナーメソッドはonEventChange()です。

public class IbnRushdOrientation implements ServiceListener<Orientation>
{
    private IbnRushdObject object = null;

    public IbnRushdOrientation(IbnRushdObject obj)
    {
        object = obj;
    }

    @Override
    public void onEventChange(Orientation arg0)
    {
        IbnRushdRotation hrot = new IbnRushdRotation();
        hrot.setFixed(0, 0, 1, 0);
        hrot.setIncremental((float)arg0.getHorizontalAngle());
        hrot.setPermanent(false);

        IbnRushdRotation vrot = new IbnRushdRotation();
        vrot.setFixed(0, 1, 0, 0);
        vrot.setIncremental((float)arg0.getVerticalAngle());
        vrot.setPermanent(false);

        object.addTransformation(hrot);
        object.addTransformation(vrot);
    }
}

moveDraw()メソッドfor(IbnRushdTransformation trans: transformations)でConcurrentModificationExceptionが発生します。

何か案は?前もって感謝します!

4

1 に答える 1

1

オブジェクトを繰り返し処理しているため、リストからオブジェクトを削除することはできません。それが例外の原因です。

forループ(transformations.iterator())の代わりにイテレーターを使用してリストを反復した場合は、iterator.remove()を呼び出して、反復中にリストを安全に削除できます。

「Iterator.removeは、反復中にコレクションを変更する唯一の安全な方法であることに注意してください。反復の進行中に基になるコレクションが他の方法で変更された場合、動作は指定されません。」

http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html

于 2012-05-01T14:33:06.350 に答える