diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/contrib/singleton.clj | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/clojure/contrib/singleton.clj b/src/clojure/contrib/singleton.clj index 4761581d..02b89f3b 100644 --- a/src/clojure/contrib/singleton.clj +++ b/src/clojure/contrib/singleton.clj @@ -1,7 +1,7 @@ ;;; singleton.clj: singleton functions ;; by Stuart Sierra, http://stuartsierra.com/ -;; April 9, 2009 +;; April 14, 2009 ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use ;; and distribution terms for this software are covered by the Eclipse @@ -12,16 +12,40 @@ ;; 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 clojure.contrib.singleton) -(defn singleton - "Returns a memoized version of a function with no arguments. The - memoized version caches the function's return value. +(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. - This is useful for lazily creating global objects that are expensive - to initialize. Warning: Make sure you really want a single global - instance, and not one instance per thread." + 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)))) |