2024 State of Clojure 问卷调查中分享您的想法!

欢迎!请在关于页面了解更多关于如何使用本站的信息。

0投票
Clojure
{{thread-bound?}} 对于未由当前线程绑定的 thread-local 绑定返回 true。这与文档字符串相矛盾,文档字符串中声明如果返回 true,{{set!}} 应该成功。

这里有一个示例 REPL 会话,其中一个线程建立了一个绑定,然后将这些绑定传递给第二个线程,第二个线程检查 thread-bound? 以确定是否可以设置绑定,thread-bound? 返回 true 表明可以设置绑定,第二个线程尝试设置绑定,并引发了 IllegalStateException


    Clojure 1.5.1
    user=> (def ^:dynamic *set-me* nil)
    #'user/*set-me*
    user=> (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? #'*set-me*) (set! *set-me* (inc *set-me*)))))))
    #'user/try-to-set
    user=> (try-to-set)
    IllegalStateException 无法设置:*set-me* 来自非绑定的线程 clojure.lang.Var.set (Var.java:230)
    user=>


方法:在存在绑定并且该绑定不是由当前线程建立的场景下, thread-bound? 应该返回 false。这个补丁为 Var 添加了一个新功能,因为核心对非公众 Var$TBox 没有可见性。

补丁:thread-bound.diff

审核:Alex Miller

4 个答案

0投票

评论者:pjstadig

我已经附加了一个补丁,该补丁将 clojure.lang.Var 和 clojure.core/thread-bound? 更改为只在 Var 可用 set! 时返回 true。

0投票
by

评论者:alexmiller

是否有REPL示例?

0投票
by

评论者:joegallo

当然,Alex,这是我今晨运行的一个REPL示例。

`; nREPL 0.1.7
user> (def ^:dynamic set-me nil)

'user/set-me

user> (defn try-to-set [] (binding [*set-me* 1] (doall (pcalls #(if (thread-bound? set-me) (set! set-me (inc set-me)))))))

'user/try-to-set

user> (try-to-set)
IllegalStateException Can't set!: set-me from non-binding thread clojure.lang.Var.set (Var.java:230)
user>`

0投票
by
参考:https://clojure.atlassian.net/browse/CLJ-1077(报道者:pjstadig)
...