简体   繁体   中英

ConcurrentModificationException in synchronized collection

I am using SynchronizedCollection.containsAll problem is facing is when i ever i run the following code i am getting ConcurrentModification Exception .

From my understanding code should terminate without any exception.

public class Main {

    public static void main(String[] args) {
        List l1 = new LinkedList(), l2 = new LinkedList();
        for (int i = 0; i < 100000; i++) {
            l1.add("" + i);
        }
        for (int i = 0; i < 100000; i++) {
            l2.add("" + i);
        }
        // reverse to make the search take a little longer
        Collections.reverse(l2);
        final List sl1 = Collections.synchronizedList(l1);
        final List sl2 = Collections.synchronizedList(l2);

        new Thread() {
            public void run() {
                // synchronized (sl2) {
                sl1.containsAll(sl2);
                // }
            }
        }.start();
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                sl2.add("3");
            }
        }.start();
    }

}

Can some one help me understand why i am getting this exception.

As per the documentation of Collections::synchronizedList

It is imperative that the user manually synchronize on the returned list when iterating over it.

In your example, when you run sl.containsAll(sl2) , you iterate over sl2 without synchronizing on sl2 . That's admittedly an implementation detail of the containsAll method but it is clearly indicated in the javadoc :

This implementation iterates over the specified collection, checking each element returned by the iterator in turn to see if it's contained in this collection.

You can fix the problem by synchronizing on sl2 (ie uncomment the code that you have commented out).

I checked the code, i think exception is intended but if current code

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {return c.containsAll(coll);}
        }

is changed to....

public boolean containsAll(Collection<?> coll) {
synchronized(mutex) {
               synchronized(coll) {
              return c.containsAll(coll);}}
        }

Then the problem will be fixed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM