【问题标题】:Problems with adding string to a list by many threads多个线程将字符串添加到列表的问题
【发布时间】:2014-03-20 09:35:10
【问题描述】:

这是Do I need a concurrent collection for adding elements to a list by many threads?的后续帖子

那里的每个人都专注于扩展列表。我知道这可能是个问题,但是.. 添加元素呢?那是线程安全的吗?

示例代码

static final Collection<String> FILES = new ArrayList<String>(1000000);

并且我在许多线程中执行(我添加的元素少于 1000000 个)

FILES.add(string)

那个线程安全吗?这样做可能会出现什么问题?

【问题讨论】:

  • 没有。 ArrayList 不是线程安全的。使用 Collections.synchronizedList(new ArrayList()); .参考stackoverflow.com/questions/11360401/java-synchronized-list
  • 我在帖子中解释过。你还有什么不明白的?在执行添加操作的那一刻,您可以简单地得到不同的结果。再次阅读您所引用的我的帖子,并尝试更准确地问我您在该解释中不理解的内容以及缺少的内容。
  • 我认为我对您的第一个问题做出了正确的回答。因此,您只需删除该问题即可。我在第一个中做了一些更新,以便更准确地解释它。

标签: java multithreading collections thread-safety


【解决方案1】:

ArrayList&lt;String&gt; 本身不同步。请改用Collections.synchronizedList(new ArrayList&lt;String&gt;())

【讨论】:

【解决方案2】:

使用Collections.syncronizedList(new ArrayList&lt;String&gt;(1000000))

【讨论】:

  • 我为什么要这样做?这就是我在问题中提出的问题
【解决方案3】:

即使列表没有展开,它也会保持其内部状态,例如当前大小。在更广泛的意义上,ArrayList 被指定为一个非线程安全的可变对象,因此在其上同时调用任何 mutator 方法是非法的。

【讨论】:

    【解决方案4】:
    public boolean add(E e) {
         ensureCapacityInternal(size + 1);  // Increments modCount!!
         elementData[size++] = e;
         return true;
    }
    

    这是 7u40-b43 中 ArrayList 的源代码。 ensureCapacityInternal() 方法不是线程安全的,size++ 也不是。 size++分三步完成,1)获取大小,2)大小+1,3)写回新值。

    【讨论】:

      猜你喜欢
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      相关资源
      最近更新 更多