diff options
Diffstat (limited to 'modules/singleton/src')
-rw-r--r-- | modules/singleton/src/main/clojure/clojure/contrib/singleton.clj | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/modules/singleton/src/main/clojure/clojure/contrib/singleton.clj b/modules/singleton/src/main/clojure/clojure/contrib/singleton.clj new file mode 100644 index 00000000..2545d9c7 --- /dev/null +++ b/modules/singleton/src/main/clojure/clojure/contrib/singleton.clj @@ -0,0 +1,54 @@ +;;; singleton.clj: singleton functions + +;; by Stuart Sierra, http://stuartsierra.com/ +;; April 14, 2009 + +;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use +;; and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this +;; distribution. By using this software in any fashion, you are +;; agreeing to be bound by the terms of this license. You must not +;; remove this notice, or any other, from this software. + + +;; Change Log: +;; +;; April 14, 2009: added per-thread-singleton, renamed singleton to +;; global-singleton +;; +;; April 9, 2009: initial version + + +(ns + ^{:author "Stuart Sierra", + :doc "Singleton functions"} + clojure.contrib.singleton) + +(defn global-singleton + "Returns a global singleton function. f is a function of no + arguments that creates and returns some object. The singleton + function will call f just once, the first time it is needed, and + cache the value for all subsequent calls. + + Warning: global singletons are often unsafe in multi-threaded code. + Consider per-thread-singleton instead." + [f] + (let [instance (atom nil) + make-instance (fn [_] (f))] + (fn [] (or @instance (swap! instance make-instance))))) + +(defn per-thread-singleton + "Returns a per-thread singleton function. f is a function of no + arguments that creates and returns some object. The singleton + function will call f only once for each thread, and cache its value + for subsequent calls from the same thread. This allows you to + safely and lazily initialize shared objects on a per-thread basis. + + Warning: due to a bug in JDK 5, it may not be safe to use a + per-thread-singleton in the initialization function for another + per-thread-singleton. See + http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025230" + [f] + (let [thread-local (proxy [ThreadLocal] [] (initialValue [] (f)))] + (fn [] (.get thread-local)))) |