proffreda

Use of refs and dosync for creating transactions

Aug 29th, 2016
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.48 KB | None | 0 0
  1. #example of usage of atoms and swap!
  2.  
  3. (def counter (atom 0))
  4.  
  5. (swap! counter inc)
  6. ;; @counter -> 0
  7. ;; @counter -> 1
  8.  
  9. ; Let’s create 2 threads that increment counter two times:
  10.  
  11. (let [n 2]
  12. (future (dotimes [_ n] (swap! counter inc)))
  13. (future (dotimes [_ n] (swap! counter inc))))
  14.  
  15. ;; @counter -> 5
  16.  
  17. #example of usage of atoms and swap! with side-effects
  18.  
  19. (defn inc-print [val thd-id]
  20. (println “thread“, thd-id, “counter:“, val)
  21. (inc val))
  22.  
  23. Create three threads with printing side-effects. We will see extra print lines from when the swap! needed to retry because of another thread modifying the value before it could set it.
  24.  
  25. (def counter (atom 0))
  26.  
  27. (let [n 2]
  28. (future (dotimes [_ n] (swap! counter inc-print :a)))
  29. (future (dotimes [_ n] (swap! counter inc-print :b)))
  30. (future (dotimes [_ n] (swap! counter inc-print :c))))
  31. ;;@counter -> 6
  32.  
  33. #example of usage of refs and dosync for creating #transactions which apply alter to update refs
  34.  
  35. ;; Create 2 bank accounts
  36. (def acc1 (ref 100))
  37. (def acc2 (ref 200))
  38.  
  39. ;; How much money is there?
  40. (println @acc1 @acc2)
  41. ;; => 100 200
  42.  
  43. ;; Either both accounts will be changed or none
  44. (defn transfer-money [a1 a2 amount]
  45. (dosync
  46. (alter a1 - amount)
  47. (alter a2 + amount)
  48. amount)) ; return amount from dosync block and function (just for fun)
  49.  
  50. ;; Now transfer $20
  51. (transfer-money acc1 acc2 20)
  52. ;; => 20
  53.  
  54. ;; Check account balances again
  55. (println @acc1 @acc2)
  56. ;; => 80 220
  57. ;; => We can see that transfer was successful
  58.  
  59.  
  60. #Another example with 2 refs
  61.  
  62. (def alice-height (ref 1))
  63. (def right-hand-bites (ref 10))
  64.  
  65. (defn eat-from-right-hand []
  66. (dosync (when (pos? @right-hand-bites)
  67. (alter right-hand-bites dec)
  68. (alter alice-height #(* % 2)))))
  69.  
  70. (let [n 2]
  71. (future (dotimes [_ n] (eat-from-right-hand)))
  72. (future (dotimes [_ n] (eat-from-right-hand)))
  73. (future (dotimes [_ n] (eat-from-right-hand))))
  74.  
  75.  
  76. @alice-height
  77. ;; -> 64
  78. @right-hand-bites
  79. ;; -> 4
  80.  
  81. #example of usage of commute to improve performance
  82. (def alice-height (ref 1))
  83. (def right-hand-bites (ref 10))
  84.  
  85. (defn eat-from-right-hand []
  86. (dosync (when (pos? @right-hand-bites)
  87. (commute right-hand-bites dec)
  88. (commute alice-height #(* % 2)))))
  89.  
  90. (let [n 3]
  91. (future (dotimes [_ n] (eat-from-right-hand)))
  92. (future (dotimes [_ n] (eat-from-right-hand)))
  93. (future (dotimes [_ n] (eat-from-right-hand))))
  94.  
  95.  
  96. @alice-height
  97. ;; -> 512
  98.  
  99. @right-hand-bites
  100. ;; -> 1
Advertisement
Add Comment
Please, Sign In to add comment