Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency Clojure删除ref中向量的第一个(或最后一个)元素_Concurrency_Clojure_Atomicity - Fatal编程技术网

Concurrency Clojure删除ref中向量的第一个(或最后一个)元素

Concurrency Clojure删除ref中向量的第一个(或最后一个)元素,concurrency,clojure,atomicity,Concurrency,Clojure,Atomicity,我需要的是一个简单的队列,在这里我可以放置任务,并从工作人员那里一个接一个地检索它们(无需维护任务的顺序) 我写了这样的东西: ;; Definition (def q (ref [])) ;; Put (defn put-in-queue [i] (dosync (alter q conj i))) ;; Get (defn get-from-queue [] (dosync (let [v (peek q)] (alter q pop) v)))

我需要的是一个简单的队列,在这里我可以放置任务,并从工作人员那里一个接一个地检索它们(无需维护任务的顺序)

我写了这样的东西:

;; Definition
(def q (ref []))

;; Put
(defn put-in-queue [i]
  (dosync (alter q conj i)))

;; Get
(defn get-from-queue []
  (dosync
    (let [v (peek q)]
      (alter q pop)
      v)))

这是正确的解决方案吗?(可能还有更好的解决方案)

您应该使用
clojure.lang.PersistentQueue
,这是一个适合该作业的工具,以及所有这些:)

以下样本“借用”自:


请参阅以了解详细信息。

正如dsm所指出的,当您需要队列时,请使用队列,对于确实需要向量并希望在末尾添加内容并从前面删除内容的情况,
subvec
conj
都是向量上的O(1)函数

user> (subvec [1 2 3] 1)
[2 3]
user> (conj [1 2 3] 4)
[1 2 3 4]
user> (-> [] (conj 1 2) (conj 3) (subvec 1))

正确的解决方案很可能是使用
java.util.concurrent
队列
j.u.c
队列非常健壮,非常适合任务,在Clojure中工作也很好


对于5个生产者、2个消费者和以两种方式实现的有限大小队列的场景,请参见SO问题,以进行比较:首先是使用
c.l.PersistentQueue
,其次是使用
j.u.c.LinkedBlockingQueue

问题是关于多线程环境的,不只是使用subvec。
clojure.core/subvec
保留基础向量,因此这将防止所有条目无限期地符合GC的条件。(与此相反,
clojure.core.rrb vector/subvec
执行实际切片,丢弃给定索引范围之外的条目。)
user> (subvec [1 2 3] 1)
[2 3]
user> (conj [1 2 3] 4)
[1 2 3 4]
user> (-> [] (conj 1 2) (conj 3) (subvec 1))