并发访问非同步Java ArrayList

时间:2016-03-11 22:45:18

标签: java multithreading arraylist concurrency java-memory-model

想象一下以下场景:

我有一个标准的Java ArrayList<String>

ArrayList<String>由多个线程访问,没有显式同步,受以下约束条件限制:

  1. 可能同时发生多次读取(可能与下面描述的写入同时发生)。所有读取都调用iterator()上的ArrayList<String>方法,并专门使用返回的Iterator<E>(迭代器不在线程之间共享)。 Iterator<String>上调用的唯一方法是hasNext()next()(未调用remove()方法)。
  2. 一个线程可能会写入列表(可能与读取并发但不与其他写入并发)。每次写入仅调用add(String)上的remove(Object)ArrayList<E>方法。
  3. 我知道以下是真的:

    1. 读取的线程可能会看到过时的数据。
    2. 读取的主题可能会遇到ConcurrentModificationException
    3. 除上述两个问题外,还有其他问题吗?

      我正在寻找具体的例子(如果 x y 为真,那么 z 将会出现,其中 > z 很糟糕)。它必须是实际上可以发生的事情。请尽可能提供引文。

      (我个人认为其他失败是可能的,但我一直面临挑战,想出上述场景不适合生产代码的具体例子。)

1 个答案:

答案 0 :(得分:3)

我希望您的读者或编写者也可以获得ArrayIndexOutOfBounds异常或空指针异常,因为他们可以看到底层数组的不一致状态。

你真的受到ArrayList类的详细实现的支配 - 这可能因环境而异。有可能JVM可以使用本机代码实现该类,在没有同步的情况下读取时可能导致更糟的未定义行为(JVM崩溃)。

我将在ConcurrentModificationException reference page的文字中添加此内容:

  

请注意,无法保证快速失败的行为,因为一般来说,在存在不同步的并发修改时,无法做出任何硬性保证。失败快速操作会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序的正确性是错误的:ConcurrentModificationException应该仅用于检测错误。

简而言之,除了过时的数据和ConcurrentModificationException之外,你不能依赖于任何不好的事情。