【问题标题】:Mutate Non thread safe collections改变非线程安全的集合
【发布时间】:2016-08-16 21:50:44
【问题描述】:

谁能向我解释在 java 中改变一个非线程安全且被多个线程使用的集合的后果?

【问题讨论】:

标签: java thread-safety


【解决方案1】:

结果未定义且有些随机。

对于设计为快速失败的 JDK 集合,您可能会收到 ConcurrentModificationException。与任何其他类不同,这确实是集合线程安全特有的唯一结果。

可能会出现线程不安全类通常会出现的问题:

  • 集合的内部状态可能已损坏。
  • 突变可能看起来是成功的,但实际上,在任何给定时间,其他线程可能看不到更改。它们可能一开始是不可见的,后来变得可见。
  • 这些更改实际上可能在轻负载下成功,但在大量线程争用的重负​​载下随机失败。
  • 如上面评论中所述,可能会出现竞争条件。

还有很多其他的可能性,但没有一个是令人愉快的。最糟糕的是,当系统受到压力时,这些事情往往会在生产中最常暴露出来。

简而言之,您可能不想这样做。

【讨论】:

    【解决方案2】:

    最常见的结果是它看起来有效,但并非一直有效。

    这可能意味着您遇到了问题

    • 在一台机器上工作,但在另一台机器上不工作。
    • 工作了一段时间,但一些明显不相关的更改导致您的程序中断。
    • 如果您没有使用线程安全的数据结构,您不知道是否是多线程问题。

    可能发生的事情是;

    • 您很少/随机遇到错误和奇怪的行为
    • 您的代码进入无限循环并停止工作(HashMap 曾经这样做)

    唯一的选择是;

    • 限制线程之间共享的状态量,最好完全没有。
    • 要非常小心数据的更新方式。
    • 不要依赖单元测试,您必须了解代码在做什么,并确信它在所有可能的情况下都能正确运行。

    【讨论】:

      【解决方案3】:

      不保证数据结构的不变量。

      例如: 如果线程 2 在线程 1 添加到 DS 时进行读取,则线程 1 可能会考虑添加了此元素,而线程 2 尚未看到该元素已添加。

      有很多不是线程安全的数据结构,在多线程环境中仍然可以正常工作(即不抛出),并且它们甚至可能在某些情况下正确执行(例如,如果您没有执行任何操作)写入数据结构)。

      为了完全理解这个主题,建议探索并发系统中发生的不同类别的错误:这个简短的文档似乎是一个好的开始。

      http://pages.cs.wisc.edu/~remzi/OSTEP/threads-bugs.pdf

      【讨论】:

        猜你喜欢
        • 2013-07-06
        • 2013-12-10
        • 2012-10-17
        • 1970-01-01
        • 1970-01-01
        • 2011-02-28
        • 2011-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多