Google Groups

java.lang.IllegalArgumentException: More than one matching method found: submit - when "letting" an ExecutorService


Alf Jul 16, 2011 4:13 AM
Posted in group: Clojure
Hi guys. Experimenting a bit with code from "The joy of Clojure", and
I ran into a little problem. Trying to run this in the REPL gives the
following error:

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