我正在学习Clojure中的并发性。
我在http://dev.clojure.org/display/design/Scheduled+Events遇到了一个声明(斯图尔特塞拉?)声明:
- Clojure函数无法在没有阻塞或Java互操作的情况下将时间用于控制流程
- Java interop(ScheduledThreadPoolExecutor)不知道线程局部绑定
我不理解这些说法并请求澄清,也许是一个例子。具体做法是:
非常感谢!
答案 0 :(得分:4)
好的,我想我明白了。
假设你试试这个:
(def pool (atom nil))
(defn- thread-pool []
(or @pool
(reset! pool (ScheduledThreadPoolExecutor. 1))))
(def ^:dynamic *t* 0)
(binding [*t* 1]
(future (println "first example:" *t*)))
(binding [*t* 1]
(.schedule (thread-pool) (fn [] (println "second example:" *t*)) 0
TimeUnit/SECONDS))
(binding [*t* 1]
(.schedule (thread-pool) (bound-fn [] (println "third example:" *t*)) 0
TimeUnit/SECONDS))
输出将是:
first example: 1
second example: 0
third example: 1
在第一种情况下,未来的宏用私有函数binding-conveyor-fn包装主体,它保留了词法范围内的调用线程的绑定帧,并在调用包装函数之前恢复它。
在第三种情况下,bound-fn将调用线程的绑定推送到帧上,执行函数体,然后弹出绑定。
在第二种情况下,没有人保存每个线程的绑定 - 一个Java类肯定不知道它们,所以我们下降到 t Var的根值。
我希望那里有人觉得这很有意思。