Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Tree: 8342756e46
Fetching contributors…

Cannot retrieve contributors at this time

71 lines (58 sloc) 2.15 KB
(ns joy.locks
"Examples for locking from section 11.5"
(:refer-clojure :exclude [aget aset count seq])
(:use [joy.mutation :only (dothreads!)]))
(defprotocol SafeArray ;; #: SafeArray features a small set of functions
(aset [this i f])
(aget [this i])
(count [this])
(seq [this]))
(defn make-dumb-array [t sz]
(let [a (make-array t sz)]
(count [_] (clojure.core/count a))
(seq [_] (clojure.core/seq a))
(aget [_ i] (clojure.core/aget a i)) ;; #: aget and aset are unguarded
(aset [this i f]
(clojure.core/aset a i (f (aget this i)))))))
(defn pummel [a]
(dothreads! #(dotimes [i (count a)] (aset a i inc)) :threads 100))
(defn make-safe-array [t sz]
(let [a (make-array t sz)] ;; #: Array creation is the same
(count [_] (clojure.core/count a))
(seq [_] (clojure.core/seq a))
(aget [_ i] ;; #: aget is locked
(locking a
(clojure.core/aget a i)))
(aset [this i f] ;; #: aset is locked
(locking a
(clojure.core/aset a i (f (aget this i)))))))) ;; #: aset uses aget
(defn lock-i [target-index num-locks] (mod target-index num-locks))
(import 'java.util.concurrent.locks.ReentrantLock)
(defn make-smart-array [t sz]
(let [a (make-array t sz) ;; #: The array
Lsz (/ sz 2)
L (into-array (take Lsz ;; #: The locks
(repeatedly #(ReentrantLock.))))]
(count [_] (clojure.core/count a))
(seq [_] (clojure.core/seq a))
(aget [_ i]
(let [lk (clojure.core/aget L (lock-i (inc i) Lsz))]
(.lock lk) ;; #: Explicit locking
(clojure.core/aget a i)
(finally (.unlock lk))))) ;; #: Explicit unlocking
(aset [this i f]
(let [lk (clojure.core/aget L (lock-i (inc i) Lsz))]
(.lock lk)
(clojure.core/aset a i (f (aget this i))) ;; #: Reentrant locking
(finally (.unlock lk))))))))
(def S (make-smart-array Integer/TYPE 8))
(def A (make-safe-array Integer/TYPE 8))
(def D (make-dumb-array Integer/TYPE 8))
Jump to Line
Something went wrong with that request. Please try again.