【发布时间】:2021-01-24 09:38:52
【问题描述】:
class ThreadUnsafe {
static final int THREAD_NUMBER = 2;
static final int LOOP_NUMBER = 200;
public static void main(String[] args) {
ThreadUnsafe test = new ThreadUnsafe();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(() -> {
test.method1(LOOP_NUMBER);
}, "Thread" + i).start();
}
}
ArrayList<String> list = new ArrayList<>();
public void method1(int loopNumber) {
for (int i = 0; i < loopNumber; i++) {
method2();
method3();
}
}
private void method2() {
list.add("1");
}
private void method3() {
list.remove(0);
}
}
上面的代码抛出
java.lang.IndexOutOfBoundsException: Index: 0, Size: 1
我知道 ArrayList 不是线程安全的,但是在示例中,我认为每个 remove() 调用都保证在至少一个 add() 调用之前,因此即使顺序混乱,代码也应该没问题像下面这样:
thread0: method2()
thread1: method2()
thread1: method3()
thread0: method3()
这里需要一些解释,请。
【问题讨论】:
-
ArrayList 本身不是线程安全的,因此如果两个线程同时执行 add 或 remove 调用,可能会发生不好的事情。
-
你能提个问题吗?
-
@Milgo 为什么会抛出 java.lang.IndexOutOfBoundsException?代码执行顺序可能会混乱,但我想不出会发生 IndexOutOfBoundsException 的情况。
-
@handhand 这些操作不是原子的,所以当一个正在进行时,列表的状态没有很好地定义。正如您自己所说,“ArrayList 不是线程安全的”。你认为这意味着什么?如果您想查看到底发生了什么,请在调试器下运行您的程序,并在 IndexOutOfBoundsException 上设置一个断点。如果您添加完整的堆栈跟踪,有人可能会准确地告诉您发生了什么。
标签: java multithreading arraylist