Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prove arraylist is not thread safe with a test?

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();
}
}
like image 443
NeplatnyUdaj Avatar asked Sep 24 '13 13:09

NeplatnyUdaj


People also ask

How to make ArrayList thread-safe?

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.

How to check if access to ArrayList is synchronized (thread safe)?

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:

What is thread safety in Java?

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."

How do I know if ArrayList is synchronized in Java?

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.


1 Answers

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 

:)

like image 118
NeplatnyUdaj Avatar answered Oct 20 '22 01:10

NeplatnyUdaj