I am using ArrayList and I want an example of Exception in case if multiple threads try to access the same list without synchronization ? I done this in single threaded application in which if we remove an element from list while iteration it throws ConcurrentModificationExceptoin but I want to achieve the same in multi threaded environment. If anyone could give me an example of that would be highly appreciated ?
package com.test2;
public class ThreadTest extends Thread {
List list = new ArrayList<String>();
@Override
public void run() {
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add("6");
list.add("7");
list.add("8");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
public static void main(String[] args) {
Thread th1 = new ThreadTest();
Thread th2 = new ThreadTest();
Thread th3 = new ThreadTest();
th1.start();
th2.start();
th3.start();
try {
th1.join();
th2.join();
th3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Since you are creating separate copy of
List
for each thread hence there is no chance to get this exception.Just make the
List
as shared resource then you will encounter this exception:sample code:
Output:
You're accessing a separate list instance in each of your threads. Since each list is only accessed by one thread, you can't get a concurrency error.
That declares an instance field. Therefore, each call to
new ThreadTest()
creates a new list. In order to make all theThreadTest
instances use the same list, try making the fieldstatic
(i.e. a class field):As for how an error can happen, take a look at the code for
ArrayList
'sadd
method:If two threads call
add
at the same time, they could process theelementData[size++] = e
statement at the same time. Thesize
field is not declaredvolatile
; therefore, the two threads could end up writing to the same index in theelementData
array.Even if
size
were declaredvolatile
, thesize++
operation is not atomic. See How to model a situation, when i++ is corrupted by simultaneously executing threads? for an example of how an operation likesize++
can fail in a multithreaded environment.Finally, if you don't understand what
volatile
and atomic mean in the Java context, you really need to read up on concurrent programming in Java before you write any multithreaded code. It will be a worthwhile investment as you'll save yourself a lot of headaches by understanding these concepts.Quick answer:
Output:
Note: As @Braj and @DaoWen said you are using different instances. Either use their suggestions or pass the list variable in the constructor of your class (ThreadTest).
If I understand your question, yes change this
by using
Collections.synchronizedList(List)
to something like (and don't use raw types),From the javadoc,