Pular para o conteúdo

Filas, Concorrencia e Threads em Clojure

Este capítulo complementa o uso de clojure.lang.PersistentQueue e aborda conceitos de concorrência, controle de fluxo, tratamento de erros e interoperação com Java para trabalhar com Thread.

Para controlar o tamanho da fila, podemos usar if e a função count:

(def limite 5)
(defn adicionar-na-fila [fila elemento]
(if (< (count fila) limite)
(conj fila elemento)
(do
(println "Fila cheia!")
fila)))
(def fila clojure.lang.PersistentQueue/EMPTY)
(def fila (adicionar-na-fila fila :a))
;; => #queue [:a]

A função count funciona com qualquer coleção Clojure:

(count fila)
;; => 1

Para lançar exceções com informações contextuais:

(throw (ex-info "Erro de processamento" {:codigo 500 :detalhe "Falha no servidor"}))

Para capturar:

(try
(throw (ex-info "Algo deu errado" {:motivo :desconhecido}))
(catch clojure.lang.ExceptionInfo e
(println "Erro capturado:" (.getMessage e))
(println "Dados:" (ex-data e))))

Clojure é 100% compatível com Java. Podemos usar Thread diretamente:

(def t (Thread. (fn []
(println "Rodando em outra thread..."))))

Ou mais idiomaticamente com proxy ou reify para implementar interfaces:

(def t (Thread. (reify Runnable
(run [_]
(println "Executando via reify!")))))

Uma vez criada a Thread, iniciamos com start:

(.start t)

⚠️ Problemas com símbolos globais e concorrência

Seção intitulada “⚠️ Problemas com símbolos globais e concorrência”

Evitar estados globais mutáveis é essencial. Quando várias threads acessam e modificam um mesmo símbolo global, surgem problemas clássicos de race condition e inconsistência:

(def contador (atom 0))
(defn incrementar []
(dotimes [_ 1000]
(swap! contador inc)))
;; Executando em paralelo
(doseq [_ (range 10)]
(.start (Thread. incrementar)))
;; Resultado correto com atom, mas com var mutável normal daria erro

Por isso, Clojure favorece o uso de:

  • atom (atualização atômica simples)
  • ref + dosync (transações coordenadas)
  • agent (atualização assíncrona)
  • future, promise, core.async, entre outras