1

I have this below program when I run it, it crashes. Looks like there is some problem at runtime. I am not able to understand what's wrong? Can anyone provide any explanation?

public static void main(String[] args) {
    final ArrayList<Object> holder = new ArrayList<>();
    final Runnable runnable = new Runnable() {
        public void run() {
            for (int i = 1; i <= 1000000; i++) {
                holder.add(new Object());
            }

        }
    };

    new Thread(runnable).start();
    new Thread(runnable).start();
    new Thread(runnable).start();
}

Here is error message but why I am getting ArrayIndexOutOfBoundsException. Can anyone provide explanation?

Exception in thread "Thread-5" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 244
john
  • 11,311
  • 40
  • 131
  • 251

2 Answers2

4

You have multiple threads adding to an ArrayList. However, adding is not a thread-safe operation

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • Thanks Eric, I also have updated my question with error message I am getting at runtime. Also, what data structure I can use instead of ArrrayList here? – john Oct 25 '15 at 00:23
  • you can use synchronizedlist http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList%28java.util.List%29 – DreadfulWeather Oct 25 '15 at 00:25
  • ^^ or for other options http://stackoverflow.com/questions/8203864/the-best-concurrency-list-in-java – Eric J. Oct 25 '15 at 00:25
  • Sure got an idea now. What about my `ArrayIndexOutOfBoundsException` exception? Why I am getting that and how can I fix it? – john Oct 25 '15 at 00:29
  • Looks like if I use `Collections.synchronizedList` on ArrayList, then this error is gone automatically? Can you explain why I was getting `ArrayIndexOutOfBoundsException` without this? – john Oct 25 '15 at 00:40
  • 1
    Because `If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally`, Each thread has its own idea about the current size of the ArrayList. One thread thought "it's big enough", another thread interrupted it and changed the internal state of the Array List, then the first thread resumed. Note that for any given run you may or may not get this error. Given your long and tight loops, you are quite likely to though. It will not likely always be at the same point though. – Eric J. Oct 25 '15 at 00:47
0

You get this error because several threads try to access the same list. For example if Thread 1 accesses List index 20 and at the same time Thread 2 accesses List index 20 it causes problems. There is a simple solution to solve this:

public static void main(String[] args) {
    final Runnable runnable = new Runnable() {
        public void run() {
        final ArrayList<Object> holder = new ArrayList<>();
            for (int i = 1; i <= 1000000; i++) {
                holder.add(new Object());
            }

        }
    };

    new Thread(runnable).start();
    new Thread(runnable).start();
    new Thread(runnable).start();
}

I simple put the List in the run()-Method so each thread has its own list. That way it should work.

MikeVe
  • 1,062
  • 8
  • 13
  • Re, _That way it should work._ How can you say whether or not it works if the OP hasn't told us what it is supposed to _do_? – Solomon Slow Oct 25 '15 at 00:39
  • hmmm if several threads is trying to access the same list then why do we get that exception, still not able to understand. – john Oct 25 '15 at 00:41
  • Also if I use `Collections.synchronizedList` on ArrayList, then this error is gone automatically without making any other change? – john Oct 25 '15 at 00:44