PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/singleton/src/main/clojure/clojure/contrib/singleton.clj

https://github.com/laurentpetit/clojure-contrib
Clojure | 54 lines | 28 code | 10 blank | 16 comment | 1 complexity | 280f63fa124434387857082d1e2572dc MD5 | raw file
  1. ;;; singleton.clj: singleton functions
  2. ;; by Stuart Sierra, http://stuartsierra.com/
  3. ;; April 14, 2009
  4. ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use
  5. ;; and distribution terms for this software are covered by the Eclipse
  6. ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
  7. ;; which can be found in the file epl-v10.html at the root of this
  8. ;; distribution. By using this software in any fashion, you are
  9. ;; agreeing to be bound by the terms of this license. You must not
  10. ;; remove this notice, or any other, from this software.
  11. ;; Change Log:
  12. ;;
  13. ;; April 14, 2009: added per-thread-singleton, renamed singleton to
  14. ;; global-singleton
  15. ;;
  16. ;; April 9, 2009: initial version
  17. (ns
  18. ^{:author "Stuart Sierra",
  19. :doc "Singleton functions"}
  20. clojure.contrib.singleton)
  21. (defn global-singleton
  22. "Returns a global singleton function. f is a function of no
  23. arguments that creates and returns some object. The singleton
  24. function will call f just once, the first time it is needed, and
  25. cache the value for all subsequent calls.
  26. Warning: global singletons are often unsafe in multi-threaded code.
  27. Consider per-thread-singleton instead."
  28. [f]
  29. (let [instance (atom nil)
  30. make-instance (fn [_] (f))]
  31. (fn [] (or @instance (swap! instance make-instance)))))
  32. (defn per-thread-singleton
  33. "Returns a per-thread singleton function. f is a function of no
  34. arguments that creates and returns some object. The singleton
  35. function will call f only once for each thread, and cache its value
  36. for subsequent calls from the same thread. This allows you to
  37. safely and lazily initialize shared objects on a per-thread basis.
  38. Warning: due to a bug in JDK 5, it may not be safe to use a
  39. per-thread-singleton in the initialization function for another
  40. per-thread-singleton. See
  41. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025230"
  42. [f]
  43. (let [thread-local (proxy [ThreadLocal] [] (initialValue [] (f)))]
  44. (fn [] (.get thread-local))))