Skip to content

Instantly share code, notes, and snippets.

@pbalduino
Last active September 24, 2019 14:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pbalduino/87d356154a4eeee5838f to your computer and use it in GitHub Desktop.
Save pbalduino/87d356154a4eeee5838f to your computer and use it in GitHub Desktop.
Estudo para entender como swap! funciona por dentro
;; comentários iniciados com dois ; são explicações minhas
; comentários iniciados com um ; é mensagem impressa pelo código
;; um atom é uma estrutura de dados quer permite modificações atômicas
;; de valor de forma segura e síncrona em um ambiente multithread.
;; aqui definimos um atom com valor inicial 0
(def c (atom 0))
(defn incx
"Função que incrementar um valor e causa efeito colateral
exibindo na tela o nome da thread atual seguido de
'waiting' quando acaba de entrar na função ou do valor
a ser incrementado após a pausa de cinco segundos."
[val]
(println (.getName (Thread/currentThread)) "waiting")
(Thread/sleep 5000)
(println (.getName (Thread/currentThread)) val)
(inc val))
(defn start-thread
"Executa a modificação no atom c dentro de uma thread
a parte, para que possamos simular várias modificações
simultâneas no mesmo atom. Adicionei uma pausa de 100
milissegundos apenas para não bagunçar a exibição dos
dados na tela."
[]
(.start (Thread. (fn []
(swap! c incx)
;; swap! é síncrono, então se você quiser que a sua modificação cause um efeito colateral,
;; o lugar mais indicado é aqui, e não dentro da função incx.
(println (.getName(Thread/currentThread)) "c =" @c))))
(Thread/sleep 100)
"")
;; vamos criar cinco threads que vão tentar modificar o valor do atom
(repeatedly 5 start-thread)
;; a função incx é executada simultaneamente cinco vezes.
;; o valor tem um lock que só permite que uma thread o
;; modifique de cada vez.
; Thread-334 waiting
; Thread-335 waiting
; Thread-336 waiting
; Thread-337 waiting
; Thread-338 waiting
;; a primeira thread a ser invocada, 334, sai da pausa e consegue o lock
;; do valor. o valor é modificado, o lock é liberado e todos os envolvidos
;; são notificados.
; Thread-334 0
; Thread-334 c = 1
;; assim que recebe a notificação de que o lock foi liberado, swap! executa
;; novamente a função que foi passada como parâmetro.
; Thread-335 0
; Thread-335 waiting
; Thread-336 0
; Thread-336 waiting
; Thread-337 0
; Thread-337 waiting
; Thread-338 0
; Thread-338 waiting
;; mas só o swap! que chegar primeiro pega o lock. todas as outras vão ter
;; que esperar novamente pela liberação
; Thread-335 1
; Thread-335 c = 2
;; e de novo
; Thread-336 1
; Thread-336 waiting
; Thread-337 1
; Thread-337 waiting
; Thread-338 1
; Thread-338 waiting
; Thread-336 2
; Thread-336 c = 3
;; e de novo
; Thread-337 2
; Thread-337 waiting
; Thread-338 2
; Thread-338 waiting
; Thread-337 3
; Thread-337 c = 4
;; e de novo
; Thread-338 3
; Thread-338 waiting
; Thread-338 4
;; até que todo mundo consiga modificar o valor e ninguem mais
;; fique em poder do lock
; Thread-338 c = 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment