Manoj,
I laughed when read the statement about vars not being "thread-safe".
Of course they "seem to be" not thread-safe because apparently you
don't understand what vars are and how they are meant to be used.
You're "never" supposed to `def` vars to "set" their bindings because
vars are meant to be used for "thread-local" bindings and not for
"bashing in place" like a variable. Your var example is actually no
different than setting a global variable from two threads and watching
them become inconsistent in _any_ language.
The main use-case of vars is to change the binding temporarily in a
thread-local manner such that only a single thread sees the changed
binding while executing while others see the root or other temporary
bindings.
You can dynamically change the binding of a var "properly" either
through "binding" or by "set!" (you'd need that var to be declared
dynamic for this). If you want to change the "root" binding, then
you're supposed to use "alter-var-root".
As such, your example is a contrived example of "how not to use a var"
and shows the pitfalls of bashing a variable in place reasonably well.
Now the question remains, "why does Clojure allow vars to be deffed
like that?". Well, that's because in Clojure functions are held inside
vars and it's useful to recompile functions when a system (like the
REPL) is running, right?
Anyway, if you still wish to try out the "thread-safety" of vars, you
need to change your `var-incrementer` functions to this -
(defn var-incrementer [d]
(dotimes [_ 2e7]
(alter-var-root #'v inc)))
Try it out and let me know if you find more "bugs" in Clojure like this :)
Regards,
BG