I have been reading "Effective Java" Item 60, which is "Favor the use of standard exceptions".
Another general-purpose exception worth knowing about is ConcurrentModificationException. This exception should be thrown if an object that was designed for use by a single thread or with external synchronization detects that it is being concurrently modified.
Normally people face with CME
when they try remove from a collection while looping.
But in here I am interested about what would be a concise example on detecting a concurrent modification on self-implemented class object?
I expect it to be something like synchronizing on internal object and related boolean flag, if another thread confronts the flag being false, then throwing exception.
For a simple research I have found in source of ArrayList
:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
but the principle behind how modCount
is maintained. I cannot find where it is being decremented.
As for how you would implement this kind of behaviour yourself: Your class depends on some assumptions to work properly, which could be violated if access to an object is not synchronized properly. Try to check those assumptions and throw a CME if you find that they are not true.
In the example of ArrayList
, the assumption is that nobody will change the structure of the list while you are iterating over it, so ArrayList
keeps track of a modification count that is not supposed to change during an iteration.
However, this checking is only there to make it more likely that a bad access will cause a clean exception instead of weird behaviour - in other words, this exception is just a help to developers and does not need to enforce correctness, because correctness is already compromised when you encounter it.
It is a good idea to offer this kind of help where it does not impact the performance of your class much, but using e.g. synchronization to ensure correct use is probably a bad idea - then you might as well make the class threadsafe to begin with.
This is why the API documentation for ArrayList
says:
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.