In our application we got an ArrayIndexOutOfBounds exception on the ArrayList.add(Object o)
operation. The most obvious explanation is thread safety, but I wasn't able to recreate the events. I've tried creating two threads. In one I'm adding elements, in the other I'm removing them(or clearing the array), but I didn't get the exception for the second time.
I mean it's obvious it can happen by looking at the source of ArrayList, but it would be nice to be able to demonstrate it.
I've been running this test for quite some time without any exception:
public class Test {
static ArrayList a = new ArrayList();
public static void main(String[] args) throws Exception {
Thread t1 = new Thread() {
public void run() {
while (true) {
if (a.size() > 0)
a.remove(0);
}
}
};
Thread t2 = new Thread() {
public void run() {
while (true) {
a.add(new Object());
}
}
};
t2.start();
Thread.sleep(100);
t1.start();
}
}
To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method. Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception.
ArrayList.IsSynchronized Property is used to get a value which indicate whether access to the ArrayList is synchronized (thread safe). Return Value: This property returns the true if access to the ArrayList is synchronized (thread safe) otherwise it returns false. The default is false. Below programs illustrate the use of above-discussed property:
Thread-Safety is just not java dependent, its a concept in such multi threaded programming scenarios. "A piece of code is thread-safe if it only manipulates shared data structures in a manner that guarantees safe execution by multiple threads at the same time."
ArrayList.IsSynchronized Property is used to get a value which indicate whether access to the ArrayList is synchronized (thread safe). Return Value: This property returns the true if access to the ArrayList is synchronized (thread safe) otherwise it returns false. The default is false.
Thanks to comment from isnot2bad I found a problem in my assumptions. The problem is with concurrent adds, not add/remove. I was able to create a failing test:
static ArrayList a = new ArrayList(1);
public static void main(String[] args) throws Exception {
Thread t1 = new Thread() {
public void run() {
while (true) {
a.add(new Object());
}
}
};
Thread t2 = new Thread() {
public void run() {
while (true) {
a = new ArrayList(1);
a.add(new Object());
a.add(new Object());
}
}
};
t2.start();
Thread.sleep(100);
t1.start();
}
On the line with the add at the first thread, I'm getting this:
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 2
:)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With