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