Skip to content

Instantly share code, notes, and snippets.

@joinr
Created June 15, 2023 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joinr/818dab081702f3cbb80ef3d8cbc215f1 to your computer and use it in GitHub Desktop.
Save joinr/818dab081702f3cbb80ef3d8cbc215f1 to your computer and use it in GitHub Desktop.
exgenous pseuo thread-local variable concept.
(ns threadjunk
(:import [java.util.concurrent ConcurrentHashMap]
[java.util.function Function]))
;;satisfy conc hashmap's needs..
(defn Func ^Function [f]
(reify Function
(apply [this v] (f v))))
(defn get-binding! [^ConcurrentHashMap ctx k ^Function f]
(.computeIfAbsent ctx k f))
(defmacro pseudo-thread-local [[id init] & body]
`(let [ctx# (ConcurrentHashMap.)
init-fn# (Func (fn [k#] ~init))
~id (reify clojure.lang.IDeref
(deref [this#]
(get-binding! ctx# (.getId (Thread/currentThread)) init-fn#)))]
~@body))
(def seed (atom 0))
(defn test [n]
(pseudo-thread-local [id (swap! seed inc)]
(let [f (fn [x] [(inc x) :on @id])
xs (future (->> (range n)
(mapv f)))
ys (future (->> (range n)
(mapv f)))]
(doseq [x (concat @xs @ys)]
(println x)))))
;; threadjunk=> (test 10)
;; [1 :on 1]
;; [2 :on 1]
;; [3 :on 1]
;; [4 :on 1]
;; [5 :on 1]
;; [6 :on 1]
;; [7 :on 1]
;; [8 :on 1]
;; [9 :on 1]
;; [10 :on 1]
;; [1 :on 2]
;; [2 :on 2]
;; [3 :on 2]
;; [4 :on 2]
;; [5 :on 2]
;; [6 :on 2]
;; [7 :on 2]
;; [8 :on 2]
;; [9 :on 2]
;; [10 :on 2]
;; nil
(defn test2 [n]
(let [get-id (fn [] (or @id (var-set id (swap! seed inc))))
f (fn [x] [(inc x) :on (get-id)])
xs (future (->> (range n)
(mapv f)))
ys (future (->> (range n)
(mapv f)))]
(doseq [x (concat @xs @ys)]
(println x)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment