The fast failure behavior of iterators is not guaranteed because, in general, it is not possible to make any hard guarantees as to whether or not the concurrency changes occur . A fast-failing iterator will do its best to throw concurrentmodificationexception, writing a program that relies on this exception to improve the correctness of such iterators is a bad practice: The fast failure behavior of iterators should only be used to detect Bug.
It is an error detection mechanism for Java collections. The fail-fast mechanism is likely to occur when multiple threads are manipulating a collection for structural changes . Remember that it is possible, not necessarily.
Concurrentmodificationexception does not always indicate that an object has been modified concurrently by a different thread, and that the exception may be thrown if a single thread violates the rule .
The iterator calls the next (), remove () method to call the Checkforcomodification () method, which is primarily to detect modcount = = Expectedmodcount? If unequal then throws Concurrentmodificationexception exception, thus produces fail-fast mechanism.
Fail-fast Solution : (for ArrayList)
Scenario one: In the traversal process all involved change modcount worthwhile place all plus synchronized or directly use collections.synchronizedlist, so you can solve. However, it is not recommended because the synchronization lock caused by additions or deletions may block the traversal operation.
Scenario Two: Use copyonwritearraylist to replace ArrayList.
Copyonwritearraylist all mutable operations (add, set, and so on) are implemented by a new copy of the underlying array .
This class produces more overhead , but in both cases it is well suited for use. 1: When you cannot or do not want to perform synchronous traversal, but you need to exclude conflicts from concurrent threads . 2: When the number of traversal operations greatly exceeds the number of variable operations .
Copyonwriterarraylist does not produce a concurrentmodificationexception exception at all, which means that it does not produce a fail-fast mechanism at all with iterators.
Public BooleanAdd (E paramE) {reentrantlock Localreentrantlock= This. Lock; Localreentrantlock.lock (); Try{object[] arrayOfObject1=GetArray (); inti =arrayofobject1.length; object[] ArrayOfObject2 = arrays.copyof (ArrayOfObject1, i + 1); Arrayofobject2[i] =ParamE; SetArray (ARRAYOFOBJECT2); intj = 1; returnJ; } finally{localreentrantlock.unlock (); } } Final voidSetArray (object[] paramarrayofobject) { This. Array =Paramarrayofobject; }
the red Three code above makes copyonwriterarraylist not throw concurrentmodificationexception exceptions . Their charm is to copy the original array, and then add on the copy array, which does not affect the array in the Cowiterator at all .
Any operation that changes the structure of the array (add, remove, clear, and so on), Copyonwriterarraylist will copy the existing data and modify it on the copy data , so that The data in the Cowiterator is not affected, and the reference to the original data is changed after the modification is complete . At the same time, the cost is to produce a large number of objects , while the copy of the array is quite lossy .
Java Collection (16)--Fast failure mechanism (FAIL-FAST)