为什么其他线程看不到我的ref更新?

时间:2011-11-11 21:25:46

标签: concurrency clojure

我正在使用Swing在Clojure中进行游戏。我有一个KeyListener来处理控件,但它没有更新ref。

(def move (ref :drop))

(defn get-move 
  [block state x y moves]
  (do (println @move)
      (if (check-move @move x y block state) @move
        :nothing)))



(defn listener
  [keyevent]
  (let [c (.getKeyChar keyevent)]
   (do (println c)
      (cond (= c "j") (dosync (ref-set move :left))
            (= c "l") (dosync (ref-set move :right))
            (= c "i") (dosync (ref-set move :rotate))
            (= c "k") (dosync (ref-set move :drop))))))



(defn make-keylistener
  []
 (proxy [KeyAdapter] []
  (keyPressed [event]
            (listener event))))

现在,我们的想法是更新gui的主要函数调用get-move。它检查移动参考是否在游戏中有效,如果是,则返回它。侦听器附加到JPanel并根据按键更改引用。监听器工作正常 - 只要按下按钮,它就会输出密钥char。我只能假设它正在改变裁判。但是,get-move总是返回相同的值 - 它永远不会看到@move的变化。我觉得我误解了Clojure中有关并发和状态的基本信息。我做错了什么,是否有更实用的方法来处理这个?

谢谢!

编辑:如果我使用原子,会出现同样的问题。

1 个答案:

答案 0 :(得分:1)

这不是并发问题。 .getKeyChar返回一个char,我将其与字符串进行比较。将条件重写为(=(str c)“j”)使其有效。