2024 Clojure状态调查!分享您的看法。

欢迎!请参阅关于页面以了解更多有关其工作原理的信息。

0
集合

如果有多个线程将使用(clojure.core/sort)暴露其后端数组的(可变)Java集合传递,则该集合将在多个线程中被修改。

`
user=> (def q (java.util.concurrent.ArrayBlockingQueue. 1))

'user/q

user=> (future (loop [] (.add q 1) (.remove q 1) (recur)))

object[clojure.core$future_call$reify__4393 0x4769b07b {:status :pending, :val nil}]

user=> (take 3 (distinct (repeatedly #(sort q))))
((1) () nil)
`

方法:在将coll转换为数组之前将其转换为序列,从而保留原始集合。

补丁:0001-CLJ-1763-make-sort-thread-safe.patch

其他方法

  1. 在sort中记录,与Java数组类似,Java集合由数组支持,是在原地被修改的。
  2. 将RT.toArray()更改为从Java集合中返回数组时的(非IPersistentCollection)防御性复制数组。这个方法从几个路径调用此方法,因此具有多重潜在的影响。
  3. 对于非Clojure集合,也可以使用Collections.sort()而不是将集合倾倒到数组并使用Arrays.sort()。

6 答案

0

评论者:alexmiller

文档字符串说:“如果coll是一个Java数组,它将被修改。为了避免这种情况,请对数组的副本进行排序。”这似乎在这种情况下也是一条很好的建议。

创建输入集合的序列视图将显着改变性能特征。

0

评论者:alexmiller

我认为我所说的应该是不应该为了使任意的Java集合更安全而牺牲持久性集合的性能。但是,在不影响持久性集合性能和/或更新文档字符串的情况下使其更安全仍然可能是有用的。

0

评论作者:bronsa

Alex,没有创建额外的序列,seq调用已经存在

0

评论者:alexmiller

嗯,这在某种程度上是正确的。前一种使用并没有强制实现整个序列,只有第一个元素。话虽如此,从快速测试来看,在集合上额外的开销似乎很小(由于它们的结构,向量序列实际上速度更快)

0

评论作者:stu

我认为这应该是一个文档字符串的更改,如果有什么的话。

0
参考: https://clojure.atlassian.net/browse/CLJ-1763(由bronsa报告)
...