2010年5月29日星期六

Clojure agents

Clojure agents 是用 JDK 的线程池实现的。比如 send

(defn send
[#^clojure.lang.Agent a f & args]
(. a (dispatch f args false)))

clojure.lang.Agent#dispatch 方法把 f 封装成一个 Action 对象,再把执行这个 Action 的任务代理给 Action 自身的 execute 方法。execute 方法会把自身的 action 实例扔到线程池中去执行。看看 send 的兄弟,send-off

(defn send-off
[#^clojure.lang.Agent a f & args]
(. a (dispatch f args true)))

注意到了吗?这两个函数只差一个参数,send 在调用 dispatch 的时候最后一个参数是 false,而 send-off 是 true。这个参数为真表示 Action 在执行的时候是使用 CachedThreadPool,否则使用 FixedThreadPool 。FixedThreadPool 是大小固定的线程池,所以 send 方法的 f 函数不能包含 IO 操作,而 send-off 可以。

相应地,agent 在执行时线程池会被初始化。所以,如果你的程序中使用到了 agents,在程序的最后要记得关闭线程池。如果你不关闭,在 eclipse 或者 IDEA 中你会看到程序执行完毕后标准输出窗口的结束程序的按钮仍然可用。原因就是线程池未关闭。当然关闭线程池最重要的作用是确保线程池中所有的操作都已完成,然后释放资源。结束 agents 系统,关闭线程池的函数是 shutdown-agents,不带任何参数。

没有评论: