I am trying out a code to see what happens if a thread modifies a collection while other threads read the collection. Here's the code
package threading;
import java.util.ArrayList;
public class ReadAndWrite {
static ArrayList<Integer> coll = new ArrayList<Integer>();
public static void main(String[] args) {
coll.add(1);
coll.add(3);
coll.add(5);
Thread t = new Thread() {
public void run(){
coll.add(2);
coll.add(6);
coll.add(8);
}
};
Thread t1 = new Thread() {
public void run(){
System.out.println(" collection is "+coll + " and size is "+coll.size());
}
};
Thread t2 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t3 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t4 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
Thread t5 = new Thread() {
public void run(){
System.out.println(" collection is "+coll+ " and size is "+coll.size());
}
};
t.start();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
When I start write thread first this is the response I get all the times.
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
As soon as I change the order like one below, things go haywire in response
t1.start();
t.start();
t2.start();
t3.start();
t4.start();
t5.start();
Response
collection is [1, 3, 5] and size is 3
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5] and size is 3
collection is [1, 3, 5] and size is 3
If we further experiment with ordering we'd see an error like below
Exception in thread "Thread-1" collection is [1, 3, 5, 2, 6, 8] and size is 6Exception in thread "Thread-2"
collection is [1, 3, 5, 2, 6, 8] and size is 6
collection is [1, 3, 5, 2, 6, 8] and size is 6
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at threading.ReadAndWrite$3.run(ReadAndWrite.java:28)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at threading.ReadAndWrite$2.run(ReadAndWrite.java:23)
Questions:
Will deeply appreciate guidance on above scenario, thanks in advance. Sid
Answer for question 1: Your statement that threads are supposed be running out of order is not precise. A few points: 1. Java does not specify how threads are implemented and therefore they can be implemented using native threads or green threads, green threads are a Java only construct scheduled by the JVM. How the threads are implemented may affect runtime behavior. The JVM on Linux and Windows uses native threads. 2. When you start a thread it executes for a bit and then is interrupted and a different thread runs. Your threads do so little that when you run the writer thread it runs to completion before any other threads are scheduled.
Based on the above, you cannot make any assumptions about when thread will run and how many statements they will execute, it depends on many different variables especially when using native threads which are scheduled by the OS.
Answer to Question 2: When you are iterating over ArrayList then Iterator's next() method keep track of modCount. If you modify the collection by adding or removing element then modCount will change and it will not match with the expected modCount, hence Iterator will throw ConcurrentModificationException. Therefore, even when you only have 1 writer, if you have a concurrent reader you can get a ConcurrentModificationException
CopyOnWriteArrayList is a thread safe ArrayList implementation
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.