I have two threads modifying the same object, lets say MyObject, and so have synchronized the object. But in one of the threads another object is modified and in so doing has to call MyObject.
I.e.
public void run(){
synchronized(MyObject){
...
anotherObject.modify();//<----calls MyObject
...
}
}
This is causing ConcurrentModificationExceptions. I don't know how to solve this. If I don't synchronize, I get exceptions as both threads try to call MyObject. How can I fix this?
UPDATE: The code is for the Android device. I didn't mention it before, because there are no Android specific objects in play here. The LogCat output isn't very helpful
02-03 02:47:43.660: ERROR/AndroidRuntime(5258): Uncaught handler: thread main exiting due to uncaught exception 02-03 02:47:43.670: ERROR/AndroidRuntime(5258): java.util.ConcurrentModificationException 02-03 02:47:43.670: ERROR/AndroidRuntime(5258): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64) 02-03 02:47:43.670: ERROR/AndroidRuntime(5258): at com.jjg.myapp.gameunit.findEnemy(MoveableUnit.java:656)//<---in this method Gamestate's collections are iterated through 02-03 02:47:43.670: ERROR/AndroidRuntime(5258): at com.jjg.myapp.gameunit.update(GameUnit.java:416)
The Object that I was trying to synch is essentially a GameState called gs. It houses an assortment of ArrayLists, arrays and other objects. gs is not static.
The method above where the problem occurs is:
for(GameUnit gu : this.getBase().getGameState().getAllUnits()){//<---this is the problem line.
//do some stuff...
}
getAllUnits returns an ArrayList of GameUnits (including the GameUnit calling the method - I don't need an iterator as no objects are deleted or created).
You're really asking the same question as this: Thread-safe iteration over a collection.
The simplest solution is to copy the list before iterating through it:
for(GameUnit gu : new ArrayList<GameUnit>(this.getBase().getGameState().getAllUnits()))
Alternatively you can synchronize on the collection itself (note that for this to work, you also have to synchronize wherever you're modifying the "all units" list):
ArrayList<GameUnit> units = this.getBase().getGameState().getAllUnits())
synchronized (units) {
...
}