Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one start a thread in Clojure?

I've read a lot about how great Clojure is when it comes to concurrency, but none of the tutorials I've read actually explain how to create a thread. Do you just do (.start (Thread. func)), or is there another way that I've missed?

like image 359
andrewdotnich Avatar asked Nov 20 '09 05:11

andrewdotnich


2 Answers

Clojure fns are Runnable so it's common to use them in exactly the way you posted, yes.

user=> (dotimes [i 10] (.start (Thread. (fn [] (println i))))) 0                                                              1                                                              2                                                              4                                                              5                                                              3                                                              6                                                              7                                                              8                                                              9                                                              nil 

Another option is to use agents, in which case you would send or send-off and it'll use a Thread from a pool.

user=> (def a (agent 0)) #'user/a user=> (dotimes [_ 10] (send a inc)) nil ;; ...later... user=> @a 10 

Yet another option would be pcalls and pmap. There's also future. They are all documented in the Clojure API.

like image 191
Brian Carper Avatar answered Sep 20 '22 09:09

Brian Carper


Usually when I want to start a thread in Clojure I just use future.

As well as being simple to use, this has the advantage that you avoid having to do any messy Java interop to access the underlying Java threading mechanisms.

Example usage:

(future (some-long-running-function)) 

This will execute the function asynchronously in another thread.

(def a (future (* 10 10))) 

If you want to get the result, just dereference the future, e.g:

@a => 100 

Note that @a will block until the future thread has completed its work.

like image 41
mikera Avatar answered Sep 22 '22 09:09

mikera