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

for(IbnRushdTransformation trans: transformations)moveDraw()方法中得到 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 回答