【问题标题】:How to perform clone() on Sets.newSetFromMap(map)如何在 Sets.newSetFromMap(map) 上执行 clone()
【发布时间】:2013-10-04 11:29:37
【问题描述】:

之前的代码是这样的;避免在 Vector 上出现 ConcurrentModificationException;需要迭代的地方;它在该 Vector 上的同步块内执行。因此,通过使多个线程进入 BLOCKED 状态以在不同的 API 上获取对该 Vector 的锁定,它的性能非常差。

我决定在我的项目中将Vector 替换为Collections.newSetFromMap(new ConcurrentHashMap<psConference,Boolean>());

所以将Vector改为Concurrent集合后;我已经删除了所有同步块。

但这里的问题是我的一些代码正在对该 Vector 执行 clone()。

  1. 由于我只有 Set 界面,如何在此处执行相同操作?
  2. vector clone() 是深克隆还是浅克隆?
  3. 另外请告诉我布尔值的意义ConcurrentHashMap<psConference,Boolean>

【问题讨论】:

    标签: java collections concurrency thread-safety clone


    【解决方案1】:

    但这里的问题是我的一些代码正在执行 clone() 向量。

    既然我只有 Set 界面,如何在这里做同样的事情?

    您现在使用的是Set,而不是Vector。您的SetConcurrentHashMap 支持,因此可以安全地同时迭代。我建议您使用复制构造函数,而不是克隆。

    但请注意(来自javadocs):

    但是,迭代器被设计为一次只能由一个线程使用 时间。

    话虽如此,你也可以使用CopyOnWriteArrayList,但你必须小心,因为写入成本很高,Iterator 不支持元素更改操作。

    vector clone()是深克隆还是浅克隆?

    克隆复制引用,因此很浅。

    还请告诉我Boolean 的意义 ConcurrentHashMap<psConference,Boolean>

    Boolean 值只是一个占位符,因为您将Map 用作Set。如果您查看Collection 类的源代码,您会发现添加元素时始终使用Boolean.TRUESet 实际使用的容器是Map#keySet()。所以Boolean 参数在这里实际上什么都不做,只是一个占位符。

    【讨论】:

    • 非常感谢!!!!我不知道“迭代器被设计为一次只能由一个线程使用”这一点。我认为多个迭代器可同时用于多个线程。我的坏!!!!
    • 亲爱的@ortang;您能否也回答我在codereview.stackexchange.com/questions/32280/… 的相关问题
    【解决方案2】:

    就个人而言,我希望尽可能避免并发问题。您能否发送一个抛出ConcurrentModificationException 的代码示例?也许有一种方法可以重新设计算法来避免它们。

    另外,我宁愿用@987654321@代替Vector

    要回答您的观点 (2),基于 explanation,我会说 Vector clone() 可能是一个浅克隆。顺便说一句,他们还说通常最好避免使用clone() 方法。

    【讨论】:

    • 谢谢!本;但是,必须将 SYNCHRONIZED 集合替换为另一个 SYNCH 集合以确保线程安全。在多线程环境中使用 ConcurrentHashMap 而不是 Hashtable 来获得更好的性能是孩子。
    【解决方案3】:

    请记住,集合的并发版本不会自动消除并发错误。

    不过,在您的情况下,您最好的选择是创建实现您期望的集合接口的具体包装类,将所有必要的方法委托给包装的集合,但要知道使用的数据类型并知道如何创建自己。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-04
      • 2011-07-17
      • 2019-02-03
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2022-06-20
      相关资源
      最近更新 更多