Threads no escopo JEE

Quando eu entrevisto alguém pra uma vaga de emprego, eu sempre pergunto se podemos utilizar threads em escopo JEE. Já recebi várias, resposta, algumas preocupantes, outras espertas. Resolvi fazer um post para esclarecer essa questão.

A própria documentação da Oracle deixa claro que a função do gerenciamento de threads é do próprio container. A especificação diz que é proibido o uso de threads.

The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

Permitir que a aplicação faça o controle de threads irá interferir no controle do ciclo de vida dos componentes do container. Então estamos proibidos de usar threads diretamente na aplicação (elas existem, mas controladas pelo container). O uso direto delas implicaria na violação e perda dos recursos fornecidos pelo container: segurança, clustering, controle de transação e afins.

Mesmo o controle sendo feito no container, podemos utilizar as vantagens que as threads oferecem sem comprometer a integridade do container. Na maioria dos casos, conhecer os componentes possíveis da arquitetura é suficiente para não utilizar threads diretamente. Por exemplo, um envio de e-mail em lote pode ser desenvolvido com uma fila JMS em conjunto com um MDB. Um agendamento, pode ser feito utilizando Quartz ou um Timer Service.

Além das threads, se você leu as referências acima, irá ver que não podemos nem gravar arquivos dentro do container, pois você perderia o controle da concorrência, em ambientes clusterizados você teria problemas com arquivos que não são distribuídos em várias máquinas, operações com arquivos também não são transacionais e teria problemas com segurança. Caso deseja realmente fazer isso, você terá que desenvolver esse controle manualmente, como um sistema de arquivo distribuido entre os nós do cluster, controle de transação manual como um arquivo de lock, um controle de concorrência para garantir que um arquivo seja lido ou escrito por vez, eliminando a concorrência entre os clusters e um mecanismo de detecção ou compensação de erro ou rollback em caso de falhas entre as operações utilizando arquivos. O que não é uma tarefa fácil, mas às vezes se faz necessário.

Há casos específicos que existe a necessidade de uso threads, mas devemos fazer isso sem comprometer o container, para isso há soluções como a JSR 236, que é a api de utilitários de concorrência (vulgo, usar thread do jeito certo) e se tornou padrão na especificação do JEE 7. Há uma boa referência do uso aqui e aqui.

Resumindo: Evite o uso de threads em escopo JEE, caso você identifique a necessidade, verifique se algum componente padrão resolve o seu problema, caso contrário, utilze APIs adequadas para usar threads sem comprometer os recursos fornecidos pelo JEE.

Sobre: Thiago Galbiatti Vespa

Thiago Galbiatti Vespa é mestre em Ciências da Computação e Matemática Computacional pela USP e bacharel em Ciências da Computação pela UNESP. Coordenador de projetos do JavaNoroeste, membro do JCP (Java Community Process), consultor Oracle, arquiteto de software de empresas de médio e grande porte, palestrante de vários eventos e colaborador de projetos open source. Possui as certificações: Oracle Certified Master, Java EE 5 Enterprise Architect – Step 1, 2 and 3; Oracle WebCenter Portal 11g Certified Implementation Specialist; Oracle Service Oriented Architecture Infrastructure Implementation Certified Expert; Oracle Certified Professional, Java EE 5 Web Services Developer; Oracle Certified Expert, NetBeans Integrated Development Environment 6.1 Programmer; Oracle Certified Professional, Java Programmer; Oracle Certified Associate, Java SE 5/SE 6