I have a class which extends LinkedList and implements Runnable. I also have a main class which modifies the extended LinkedList.

So, the issue is, the LinkedList is being modified by 2 threads:
main() in the main thread
and run() in the thread which is created from implementing Runnable

An example that I whipped up:

import java.util.LinkedList;

public class test2 {
	MyList extendedList = new MyList();
	
	public static void main(String[] args) {
		test2 test = new test2();
		test.extendedList.add("Hi!");   //modified here
		new Thread(test.extendedList).start();
	}

	public class MyList extends LinkedList<String> implements Runnable {

		public void run() {
			while (true) {
				for (String str : this)	{   //here is where it happens
					System.out.println(str);
					this.remove(str);  //also modified here
				}
			}
		}
		
	}
}

The console output:

Hi!
Exception in thread "Thread-0" java.util.ConcurrentModificationException
	at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
	at java.util.LinkedList$ListItr.next(Unknown Source)
	at test2$MyList.run(test2.java:16)
	at java.lang.Thread.run(Unknown Source)

I'm pretty sure the reason this is happening is because I need to Synchronize the LinkedList. How would I do that if the LinkedList is being extended and not initialized elsewhere? Maybe its something else?

This didn't do it either:

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class test2 extends Thread {
	List<String> queue = Collections.synchronizedList(new LinkedList<String>());

	public static void main(String[] args) {
		test2 test = new test2();
		test.queue.add("Hi!");
		test.start();
	}

	public void run() {
		while (true) {
			for (String str : queue) {  //still happens here
				System.out.println(str);
				queue.remove(str);
			}
		}
	}
}

I also tried using the reserved word synchronize before every function. Nada.

If the problem was making sure access to the queue was serialized, then this should have worked right?

Ahhhh, lol. I get it now. Because I'm iterating over the list, I cant remove an item from that list or else the iterator would get confused --- aka, a fail-safe iterator which throws the above error.

I had to do something like this to solve it, although I hope someone can tell me a better way....

public void run() {
		LinkedList<String> removeList = new LinkedList<String>();
		
		while (true) {
			for (String str : queue) {
				System.out.println(str);
				removeList.add(str);
			}
			queue.removeAll(removeList);
			removeList.clear();
		}
	}

I got the message again because I happened to add a string while it was iterating.... I was thinking I had 2 options... I could add another list called addList and work it the same way i did removeList, or use use a try-catch statement and have it ignore the iteration attempt and try again and again until it goes through.

try	{
     for (File file : this) {
	.....
     }
} catch (ConcurrentModificationException e) {
   //do nothing
}

Both could work, but then I thought, why not avoid the iteration all together..... I was iterating over a list while inside a while(true) loop. A small loop in an infinite loop. I changed it to just take the first str in the list (queue.getFirst()), process on that, and then remove it at the end, thus allowing the while (true) loop advance it to the next iteration.

Dont know why I didnt think of that earlier :)

Helps to type out loud... Thanks for listening DaniWeb...... LOL

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.