1

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.

3
  • Have you read Collections.synchronizedList()'s javadoc ? Commented Jun 9, 2017 at 9:19
  • 1
    Why do you think sl1 is in synchronized with sl2? Commented Jun 9, 2017 at 9:20
  • instead of Thread.sleep(100); change it to Thread.sleep(1000); and you will see Commented Jun 9, 2017 at 9:22

2 Answers 2

2

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 (i.e. uncomment the code that you have commented out).

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

That could easily lead to deadlocks and there is no reason to assume that coll is a synchronized collection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.