Thread Local

Eder Leite
SynchroTEC
Published in
3 min readDec 20, 2016

Numa aplicação web em Java, em vários momentos é muito útil manter informações em um contexto maior que o request, mas também nem tão grande com a session ou application. Nessas situações o Thread Local, pode ajudar bastante.

Mas o que é Thread Local?

Thread Local é utilizado para definir ciclo de vida dos objetos, trata-se de um tipo de escopo de acesso onde apenas a thread que está sendo executada tem acesso a esses objetos. Por tanto, se a thread foi criada dentro de um sessão de usuário, os objetos adicionados nela, estarão visíveis apenas nessa thread.

Seu escopo é parecido com o escopo de objetos estáticos. Objetos estáticos em Java são criados apenas uma vez e ficam disponíveis na memória até o fim da execução da JVM. Já na Thread Local, os objetos ficam na memória até o fim a execução da thread corrente.

Assim, é possível isolar objetos de uso “global” da thread nela mesma. Métodos executados nessa thread terão acesso ao objeto, como se fossem estáticos.

Os esquema a cima mostra a o acesso dos objetos a informações tanto no thread local de cada thread, quanto ao acesso as informações estáticas da aplicação.

Ao criar um objeto estático, qualquer uma das threads terão acesso a ela. Já no Thread Local, apenas os objetos criados pela thread terão acesso.

Onde usar?

Thread Local é muito usada em objetos DAO, para compartilhar a transação corrente entre as camadas de aplicação. Mas pode ser usada em qualquer lugar, onde necessite compartilhar recursos ou informações durante a execução da thread.

No projeto que trabalho aqui na Synchro, tínhamos problemas para compartilhar parâmetros de execução processos batch.

Um processo, executa um ou mais métodos, que por sua vez (podem) executam outros métodos encadeados. Nosso maior problema era os métodos da ponta (os últimos a ser executados), precisar de um parâmetro informado pelo processo (tela de parametrização), nesses casos, toda a cadeia de chamada desses métodos, necessitava compartilhar essa informação, com isso as assinaturas dos métodos ficaram complexas, com muitos parâmetros na assinatura.

Esquema mostra a passagem de parâmetros do processo até o último método da chamada.

O processo chama o metodoA() do Objeto1, passando os parâmetros cnpj, ano e mês. Por sua vez o metodoA() chama metodoB() do Objeto 2, passando os mesmo parâmetros e metodoC() do Objeto 3, passando apenas cnpj. Por fim, o metodoB() chama o metodoD() e metodoE() do Objeto 4, repassando os parâmetros do processo.

Caso um dia fosse necessário informar um novo parâmetro no metodoE(), no mínimo teríamos que alterar a assinatura de três métodos apenas para levar o parâmetro necessário ao metodoE(). Trabalhoso!! Além disso, na figura a cima, o metodoB() do Objeto2, poderia estar recebendo os parâmetros apenas para reparar para os métodos do Objeto4.

Resolvermos o problema usando Thread Local. Criamos um gerenciador de contexto, capaz de guardar os parâmetros do processo. Em cada uma dos objetos/métodos foi possível recuperar os parâmetros sem a necessidade de passa-los na assinatura do método. Exemplo de uma Thread Local:

No processo, bastou criar um objeto do tipo IParametrosProcesso e seta-lo no GerenciadorContexto, dessa forma:

Os métodos das classe que dependem dos parâmetros ficaram assim:

Importante: Ao finalizar a execução do processo, não esqueça de limpar o thread local, no gerenciador de contexto, chame o método clean. Isso faz-se necessário pois em um container JEE após finalizada a execução da thread, a mesma retorna ao pool, desta forma o GC não limpa automaticamente os dados, podendo causar vazamento de memória.

Se gostaram dá uma curtida aí!

Valeu galera

Originally published at edermfl.wordpress.com on February 4, 2016.

--

--