Is a Java collection guaranteed to be in a valid, usable state after a ConcurrentModificationException?
Quoting part of the quote:
Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
Conclusion: Your code is buggy and needs to be fixed, so it doesn't matter what state the collection is in.
You should never get that error in valid code. It's an exception that should never be caught and acted on.
For most collections, as long as you only have one writer, you are probably ok, but there are no guarantees. If you have multiple writers on a HashMap you can end up with a corrupt map which has an infinite loop in it's structure.
I suggest you use ReentrantLock
which has a tryLock()
method if you want to support only-obtaining-a-lock-if-it's-not-being-used approach to minimise blocking.
Another way to feed data from one thread to another is to Queue
modification tasks which the engine can pick up when not otherwise busy. This allows all access through one thread only.
BTW: A lock/unlock takes around 1 micro-second which is unlikely to make much difference to you unless you do this a lot.
The GUI thread ends up iterating over many lists of objects that are conceptually "owned" by the engine thread
Since the engine owns the data I argue that it should not openly share that data with the GUI.
Consider having the engine push data to the GUI rather than the GUI pulling (or reading directly) from the engines data structures. That way the engine has full and exclusive control of its data, as it probably should.
The downside is that this may take a significant redesign.
But the benefits may be significant enough to warrant it:
- No more
ConcurrentModificationException
- No need for locks
- No need to constantly scan data and redraw, only when an update says to.
The last point could be significant depending on how much data you are dealing with or how complex your redrawing is. Pushing updates to your GUI will give you much more flexibility to optimize if profiling reveals the need to do so. For example, you could make better use of caches on the GUI side and invalidate those caches through updates pushed from the engine.