Clojure中控制流的时间-ScheduledThreadPoolExecutor的陷阱?

Clojure中控制流的时间-ScheduledThreadPoolExecutor的陷阱?,clojure,scheduled-tasks,clojure-java-interop,Clojure,Scheduled Tasks,Clojure Java Interop,我正在学习Clojure中的并发性 我(斯图尔特·塞拉?)在上遇到一项索赔,声称: Clojure函数不能在没有阻塞或Java互操作的情况下为控制流使用时间 Java interop(ScheduledThreadPoolExecutor)不知道线程本地绑定 我不理解这些说法,恳请澄清,也许是一个例子。具体而言: ScheduledThreadPoolExecutor的现状有什么问题?因为我正在启动一个新的(绿色)线程,所以我不希望每个线程绑定都会继续 我可以安排一个普通的Clojure函

我正在学习Clojure中的并发性

我(斯图尔特·塞拉?)在上遇到一项索赔,声称:

  • Clojure函数不能在没有阻塞或Java互操作的情况下为控制流使用时间
  • Java interop(ScheduledThreadPoolExecutor)不知道线程本地绑定
我不理解这些说法,恳请澄清,也许是一个例子。具体而言:

  • ScheduledThreadPoolExecutor的现状有什么问题?因为我正在启动一个新的(绿色)线程,所以我不希望每个线程绑定都会继续
  • 我可以安排一个普通的Clojure函数,那么是什么阻止我将所需的绑定作为词汇闭合上下文发送呢
非常感谢

好的,我想我明白了

假设您尝试以下方法:

(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
在第一种情况下,future宏使用私有函数binding converter fn包装主体,该函数在词法作用域中保留调用线程的绑定框架,并在调用包装函数之前将其还原

在第三种情况下,绑定fn将调用线程的绑定推送到框架上,执行函数体,并弹出绑定

在第二种情况下,没有人保存每个线程的绑定—Java类肯定不知道这些绑定,因此我们将使用t Var的根值

我希望有人会觉得这很有趣