Java ConcurrentModificationException,即使使用同步
我有两个线程:第一个线程是渲染线程,第二个线程是处理UI操作的主线程 我得到以下错误: java.util.ConcurrentModificationException 位于java.util.AbstractList$SimpleListIterator.nextAbstractList.java:95 在com.convekta.android.chessboard.chessboard.renderGamerPiecesChessBoard.java:424 位于com.convekta.android.chessboard.chessboard.renderChessBoard.java:162 位于com.convkta.android.chessboard.ChessDrawThread.runChessDrawThread.java:41 ConcurrentModification异常的常见原因是迭代列表的更改,但我只在renderGamerPieces函数中读取它。mGamerPieces唯一可能更改的地方是loadPosition方法,但loadPosition和renderGamerPieces都在同步块内调用 也许我不明白什么。。那么这个错误是如何出现的呢 我的代码:Java ConcurrentModificationException,即使使用同步,java,android,multithreading,Java,Android,Multithreading,我有两个线程:第一个线程是渲染线程,第二个线程是处理UI操作的主线程 我得到以下错误: java.util.ConcurrentModificationException 位于java.util.AbstractList$SimpleListIterator.nextAbstractList.java:95 在com.convekta.android.chessboard.chessboard.renderGamerPiecesChessBoard.java:424 位于com.convekta
private final List<DrawablePiece> mGamerPieces = new ArrayList<DrawablePiece>();
private final Object mGamerPiecesLock = new Object();
public void loadPosition(byte[] pieces, byte[] places) {
synchronized (mGamerPiecesLock) {
mPicked = null;
mGamerPieces.clear();
for (int i = 0; i < pieces.length; i++) {
byte p = GamerUtils.UncastleRook(pieces[i]);
if (p != GamerPieces.EMPTY) {
byte pl = places[i];
if (pl <= GAME_BOARDSIZE)
mGamerPieces.add(new DrawablePiece(p,
GamerUtils.columnByCell(pl), GamerUtils.rowByCell(pl,
true)));
}
}
}
}
public void renderGamerPieces(Canvas canvas) {
...
Rect r = new Rect(0, 0, mCellSize, mCellSize);
List<DrawablePiece> over = new ArrayList<DrawablePiece>();
for (DrawablePiece d : mGamerPieces) {
if (d.isFloating()) {
over.add(d);
} else {
r.offsetTo(invert(d.getBoardCol()) * mCellSize,
invert(d.getBoardRow()) * mCellSize);
r.offset(mBoardRegion.left, mBoardRegion.top);
Bitmap pic = mPieceFactory.getBitmapPiece(d.getPiece(),
mCellSize);
if (null != pic)
canvas.drawBitmap(pic, null, r, null);
}
}
...
}
public void render(Canvas canvas) {
...
synchronized (mGamerPiecesLock) {
renderGamerPieces(canvas);
}
...
}
谢谢你的评论!我将整理我的代码-在renderGamerPieces中添加同步块,并检查是否可以从另一个同步块调用loadPosition。我通过使同步块尽可能小来进行代码重构,问题得到了解决。显然,随后有一个从一个同步块到另一个块的调用。loadPosition是从RenderGamePieces调用的吗?不,loadPosition是从其他类调用的,而不是从这个类调用的。唯一合理的解释是,您忽略了一些东西。下面是我在黑暗中拍摄的照片:renderGamePieces是公共的,但您不能在该方法中同步。您可能是从其他地方调用它,在那里您不同步。即使这不是问题所在,您也应该从该方法中进行同步,因为这对其正确性至关重要。从堆栈跟踪开始,它是从呈现调用的。作为解决方法,您可以使用CopyOnWriteArrayList。