Uma das primeiras coisas que aprendi sobre o desenvolvimento do Java EE é que não devo gerar meus próprios threads dentro de um contêiner do Java EE. Mas quando penso nisso, não sei o motivo.
Você pode explicar claramente por que isso é desencorajado?
Tenho certeza de que a maioria dos aplicativos corporativos precisa de algum tipo de trabalho assíncrono, como daemons de correio, sessões inativas, trabalhos de limpeza etc.
Portanto, se de fato não se deve gerar tópicos, qual é a maneira correta de fazer isso quando necessário?
java
multithreading
jakarta-ee
LiorH
fonte
fonte
Respostas:
É desencorajado porque todos os recursos no ambiente devem ser gerenciados e potencialmente monitorados pelo servidor. Além disso, grande parte do contexto em que um encadeamento está sendo usado é normalmente anexada ao encadeamento de execução em si. Se você simplesmente iniciar seu próprio thread (que eu acredito que alguns servidores nem mesmo permitirão), ele não poderá acessar outros recursos. O que isso significa é que você não pode obter um InitialContext e fazer pesquisas JNDI para acessar outros recursos do sistema, como JMS Connection Factories e Fontes de Dados.
Existem maneiras de fazer isso "corretamente", mas isso depende da plataforma que está sendo usada.
O commonj WorkManager é comum para WebSphere e WebLogic, além de outros
Mais informações aqui
E aqui
Também um pouco duplica este desta manhã
ATUALIZAÇÃO: Observe que esta pergunta e resposta estão relacionadas ao estado do Java EE em 2009; as coisas melhoraram desde então!
fonte
Para os EJBs, isso não é apenas desencorajado, é expressamente proibido pela especificação :
e
O motivo é que os EJBs devem operar em um ambiente distribuído. Um EJB pode ser movido de uma máquina em um cluster para outra. Threads (e soquetes e outras instalações restritas) são uma barreira significativa a essa portabilidade.
fonte
O motivo pelo qual você não deve gerar seus próprios threads é que eles não serão gerenciados pelo contêiner. O contêiner cuida de muitas coisas que um desenvolvedor iniciante pode achar difícil de imaginar. Por exemplo, coisas como pool de threads, clustering, recuperações de falhas são executadas pelo contêiner. Ao iniciar um tópico, você pode perder alguns deles. Além disso, o contêiner permite reiniciar seu aplicativo sem afetar a JVM na qual ele é executado. Como isso seria possível se houver threads fora do controle do contêiner?
Esse é o motivo pelo qual os serviços de timer J2EE 1.4 foram introduzidos. Veja este artigo para detalhes.
fonte
Utilitários de simultaneidade para Java EE
Agora existe uma maneira padrão e correta de criar encadeamentos com a API Java EE principal:
Ao usar o Concurrency Utils, você garante que seu novo encadeamento seja criado e gerenciado pelo contêiner, garantindo que todos os serviços de EE estejam disponíveis.
Exemplos aqui
fonte
Você sempre pode dizer ao contêiner para iniciar as coisas como parte de seus descritores de implantação. Eles podem fazer as tarefas de manutenção necessárias.
Siga as regras. Você ficará feliz em algum dia que você fez :)
fonte
Os encadeamentos são proibidos nos contêineres Java EE de acordo com os blueprints. Por favor, consulte os projetos para mais informações.
fonte
Não há motivo real para não fazê-lo. Eu usei o Quarz com o Spring em um aplicativo da web sem problemas. Também a estrutura de simultaneidade
java.util.concurrent
pode ser usada. Se você implementar seu próprio manuseio de encadeamento, configure os theads para deamon ou use um próprio grupo de encadeamentos de deamon para eles, para que o contêiner possa descarregar seu aplicativo da Web a qualquer momento.Mas tenha cuidado, a sessão e a solicitação do escopo do bean não funcionam em threads gerados! Além disso, outro código bloqueado
ThreadLocal
não funciona imediatamente , você precisa transferir os valores para os segmentos gerados por si mesmo.fonte
Eu nunca li que isso é desencorajado, exceto pelo fato de que não é fácil fazer corretamente.
É uma programação de baixo nível e, como outras técnicas de baixo nível, você deve ter um bom motivo. A maioria dos problemas de simultaneidade pode ser resolvida com muito mais eficiência usando construções internas, como conjuntos de encadeamentos.
fonte
Um motivo que eu encontrei se você gerar alguns encadeamentos no EJB e tentar fazer com que o contêiner descarregue ou atualize o EJB, você terá problemas. Quase sempre há outra maneira de fazer algo em que você não precisa de um Thread; basta dizer NÃO.
fonte