2

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

我写了这样的东西:

;; 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)))

是正确的解决方案吗?(也许这个任务也有更好的解决方案)

4

3 回答 3

3

您应该使用clojure.lang.PersistentQueue正确的工具来完成这项工作以及所有这些:)。

下面的示例“借用”了 Clojure 的隐藏功能

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

有关详细信息,请参阅该答案的其余部分

于 2013-10-16T15:41:19.657 回答
2

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

请参阅我对具有资格的生产者消费者SO 问题的回答,以了解具有 5 个生产者、2 个消费者和以两种方式实现的有限大小队列的情况进行比较:首先使用c.l.PersistentQueue,其次使用j.u.c.LinkedBlockingQueue

于 2013-10-18T11:55:03.127 回答
0

正如 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))
于 2013-10-16T21:01:12.697 回答