user=> (import [java.util.concurrent Executors])
java.util.concurrent.Executors
user=> (let [*pool* (Executors/newFixedThreadPool (+ 2
(.availableProcessors (Runtime/getRuntime))))]
(defn dothreads! [f & {thread-count :threads
exec-count :times
:or {thread-count 1 exec-count 1}}]
(dotimes [t thread-count]
(.submit *pool* #(dotimes [_ exec-count] (f))))))
java.lang.IllegalArgumentException: More than one matching method
found: submit (NO_SOURCE_FILE:7)
However if I define pool as a Var it seems to work fine:
user=> (import '(java.util.concurrent Executors))
java.util.concurrent.Executors
user=> (def *pool* (Executors/newFixedThreadPool
(+ 2 (.availableProcessors (Runtime/getRuntime)))))
#'user/*pool*
user=> (defn dothreads! [f & {thread-count :threads
exec-count :times
:or {thread-count 1 exec-count 1}}]
(dotimes [t thread-count]
(.submit *pool* #(dotimes [_ exec-count] (f)))))
#'user/dothreads!
(from https://github.com/joyofclojure/book-source/blob/master/src/joy/mutation.clj)
ExecutorService has three submit methods, and two with one parameter,
a Runnable and a Callable. Since Clojure functions are both, I
understand the compiler error, but why does it work when *pool* is a
Var?
The "let" version works when I cast the function to Runnable or
Callable, just wondering why there is a difference.
Cheers,
Alf