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

时间:2013-10-16 13:46:50

标签: 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)))

这是正确的解决方案吗? (也许还有更好的解决方案来完成这项任务)

3 个答案:

答案 0 :(得分:3)

你应该使用clojure.lang.PersistentQueue正确的工具来完成这项任务:)。

以下示例“借用”Hidden features of Clojure

user> (-> (clojure.lang.PersistentQueue/EMPTY)
          (conj 1 2 3)
          pop)
(2 3)

有关详细信息,请参阅the remainder of that answer

答案 1 :(得分:2)

正确的解决方案可能是使用java.util.concurrent队列,很可能是java.util.concurrent.LinkedBlockingQueuej.u.c队列非常强大,完全适合Clojure的任务和工作。

请参阅my answerProducer consumer with qualifications SO问题,了解具有5个生产者,2个消费者和有限大小队列的方案,以两种方式进行比较:首先是c.l.PersistentQueue,第二个是j.u.c.LinkedBlockingQueue

答案 2 :(得分:0)

正如dsm所指出的那样,当你需要一个队列时,使用一个队列,并且在你真正需要一个向量的时候,想要在末尾添加东西并从前面删除它们subvec和{{ 1}}是向量上的O(1)函数。

conj