我有两个线程:第一个是渲染线程,第二个线程是我处理UI操作的主线程。
我收到以下错误:
java.util.ConcurrentModificationException
at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:95)
at com.convekta.android.chessboard.ChessBoard.renderGamerPieces(ChessBoard.java:424)
at com.convekta.android.chessboard.ChessBoard.render(ChessBoard.java:162)
at com.convekta.android.chessboard.ChessDrawThread.run(ChessDrawThread.java:41)
ConcurrentModification异常的常见原因是迭代列表的更改,但我只在renderGamerPieces
函数中读取它。 mGamerPieces
方法可能更改的唯一位置是loadPosition
方法,但loadPosition
和renderGamerPieces
都在同步块内调用
也许我不明白。那么这个错误可能会出现怎么样?
我的代码:
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
。
答案 0 :(得分:0)
我通过使尽可能小的同步块进行代码重构,问题就解决了。显然,从一个同步块到另一个块的后续调用。