简单的多线程程序崩溃?

simple multithreading program crashing?

当我 运行 我有下面这个程序时,它崩溃了。看起来 运行 时间出了点问题。我不明白怎么了?谁能解释一下?

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();
}

这是错误消息,但为什么我会收到 ArrayIndexOutOfBoundsException。谁能解释一下?

Exception in thread "Thread-5" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 244

您有多个线程添加到 ArrayList。但是,添加不是线程安全的操作

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

您收到此错误是因为多个线程试图访问同一个列表。例如,如果线程 1 访问列表索引 20,同时线程 2 访问列表索引 20,则会导致问题。有一个简单的解决方案可以解决这个问题:

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();
}

我简单地将列表放在 run()-Method 中,这样每个线程都有自己的列表。这样它应该可以工作。