我正在尝试使用 Executors.newSingleThreadScheduledExecutor() 来安排 Clojure 函数。令人烦恼的是,在生成的 ScheduledFutureTask 上调用 .get() 返回 nil 而不是函数的结果。
我以希基先生对期货的实施为模型。
(ns my.ns
(:import (java.util.concurrent Executors ThreadFactory TimeUnit)))
(def ^:private thread-pool-scheduler (atom nil))
(def ^:private thread-pool-counter (agent 0))
(defn- get-and-increment-thread-id []
(-> thread-pool-counter (send inc) deref))
(def ^:private thread-factory
(reify ThreadFactory
(newThread [this f]
(let [thread (Thread. f)]
(.setName thread (format "clojure-scheduled-future-thread-pool-%d"
(get-and-increment-thread-id)))
thread))))
(defn scheduled-future-call [^Callable f ^long delay ^TimeUnit unit]
(.schedule (scheduled-futures-executor) (bound-fn* f) delay unit))
(defn start-scheduled-futures-executor! []
(reset! thread-pool-scheduler
(Executors/newSingleThreadScheduledExecutor thread-factory)))
(defn scheduled-futures-executor []
(or @thread-pool-scheduler
(start-scheduled-futures-executor!)))
一切正常,并且在适当的时候触发副作用(例如调度#(println "ok"))。但是,调用生成的 ScheduledFutureTask 的 get() 方法总是给我 nil(例如调度 #(+ 5 5))。
我尝试显式扩展 Callable,尝试省略 bound-fn*,但结果是一样的:
(defprotocol ISchedule
(schedule [this delay time-unit]))
(extend Callable
ISchedule
{:schedule (fn [this delay time-unit]
(.schedule (scheduled-futures-executor) this delay time-unit))})
我的直觉是 ScheduledExecutorService 选择 schedule(Runnable, long, TimeUnit) 而不是 schedule(Callable, long, TimeUnit),但不应该输入提示来解决这个问题吗?
非常非常感谢您的帮助或提示!