Tempo de leitura: menos de 1 minuto
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 Thead 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 tenha sido 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 um vez e ficam disponíveis na memória até o fim da execução da JVM. A diferença, é que no os objetos colocados no Thread Local 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.

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, tínhamos problemas para compartilhar parâmetros de execução processos batch. Um processo, executa um método de um ou mais métodos, que por sua vez 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 no 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.

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!!
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:
[code language=”java”]
public class GerenciadorContexto {
private static final ThreadLocal<IParametrosProcesso> contexto =
new ThreadLocal<IParametrosProcesso>();
public static IParametrosProcesso getParametros() {
return contexto.get();
}
public static void setParametros(
final IParametrosProcesso pParametros) {
contexto.set(pParametros);
}
public static void clean() {
contexto.set(null);
contexto.remove();
}
}
[/code]
No processo, bastou criar o objeto um objeto do tipo IParametrosProcesso e seta-lo no GerenciadorContexto, dessa forma:
[code language=”java”]
…
IParametrosProcesso parametros = new Parametro(cnpj, 2016, 01);
GerenciadorContexto.setParametros(parametros);
…
[/code]
Os métodos das classe que dependem dos parâmetros ficaram assim:
[code language=”java”]
public class Objeto4{
public void metodoD(){
// ano e mes são recuperados do Contexto, cujo está guardado na Thread local
final Integer ano = GerenciadorContexto.getParametros().getAno();
final Integer mes= GerenciadorContexto.getParametros().getMes();
}
public void metodoE(){
// cnpj são recuperados do Contexto, cujo está guardado na Thread local
final String cnpj = GerenciadorContexto.getParametros().getCnpj();
// se amanhã, precisar UF, basta adiciona-lo ao objeto Parametro
// que será possivel acessa-lo aqui
final String uf= GerenciadorContexto.getParametros().getUf();
}
}
[/code]
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 contener JEE após finalizada a execusão da thread, a mesma retorna ao pool, desta forma o GC não limpa automaticamente os dados, podendo causar Leak de memória.
Se gostaram curtam, comentem ou compartilhem!
E não esqueçam de responder o desafio CodeKata.
Para mais informações sobre a classe java.lang.ThreadLocal consulte o Java Doc.
Valeu galera