Last active
September 24, 2019 14:03
-
-
Save pbalduino/87d356154a4eeee5838f to your computer and use it in GitHub Desktop.
Estudo para entender como swap! funciona por dentro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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