Como trabalhar com tarefas assíncronas em Java EE

Veja neste artigo como utilizar os recursos assíncronos da plataforma Java EE.

[lead-mentoring]Este artigo abordará os recursos disponibilizados pela Java EE para executar métodos em EJBs assíncronos. Esse tipo de estratégia permite que os desenvolvedores consigam criar processos independentes uns dos outros e também viabiliza uma maior paralelização da carga de trabalho dentro de sua aplicação.

Portanto, esse artigo é muito importante para desenvolvedores que buscam melhorar o desempenho de suas soluções e entender um pouco mais as ferramentas que o Java disponibiliza para executar tarefas concorrentes e distribuídas.

Com o intuito de apresentar uma solução prática da utilização desses recursos, iremos demonstrar uma situação real onde métodos assíncronos se aplicam, abordando as alternativas que temos para conseguir executar essas tarefas. [/lead-mentoring]

A comunicação entre sistemas e métodos, dentro da área da computação, pode ser considerada um dos tópicos mais importantes na arquitetura e desenvolvimento de software, propiciando inúmeras alternativas para a integração de aplicações.

Essas alternativas, por sua vez, se dividem em dois paradigmas principais, assíncrono e síncrono, determinando o comportamento que essa comunicação deve ter.

O uso correto de cada um desses paradigmas é de extrema importância, ainda mais dentro de uma aplicação corporativa. Sendo devido aos ganhos de performance ou pela confiabilidade de resposta, a utilização do paradigma correto, de acordo com sua necessidade, é um fator importantíssimo na hora de criar um sistema ou uma nova funcionalidade.

Além disso, a utilização desses dois tipos em conjunto permite uma maior paralelização do código, podendo diminuir o impacto de tarefas demoradas e custosas em sua aplicação, trazendo uma maior qualidade ao software ao final do desenvolvimento.

O processamento assíncrono é comumente empregado por desenvolvedores através do uso da interface Runnable, que permite a criação de threads em paralelo, ou através de beans de mensagens, os MDBs.

Essas estratégias, apesar de extremamente úteis, muitas vezes não atingem o paralelismo desejado devido à dificuldade de implementação e a alta complexidade do código, características indesejadas para qualquer solução.

Portanto, pretendemos demonstrar nesse artigo as vantagens e desvantagens de utilizarmos uma abordagem mais comum, e também apresentar os recursos que a especificação da Java EE 6 trouxe para o desenvolvimento e criação de tarefas e EJBs assíncronos, explicando o motivo desses recursos serem mais adequados na implementação de um processo desse tipo.

Além disso, iremos colocar essas ideias em prática, analisando uma situação real em que a utilização de EJBs assíncronos se faz necessária e mostrar os principais ganhos desse tipo de abordagem, aplicando ela dentro de um projeto exemplo que iremos desenvolver ao longo do artigo.

Os paradigmas e suas diferenças

Antes de começarmos a desenvolver esses exemplos, precisamos entender a diferença de cada um dos paradigmas de comunicação apresentados anteriormente e suas principais diferenças, fatores essenciais para sabermos quando e onde devemos empregar cada um deles.

Iniciando pelo paradigma síncrono, esse tipo de comunicação determina que o método chamador deve aguardar a execução do método chamado antes de continuar a execução de seu código. Esse tipo de comunicação é o tipo padrão de chamadas de método em Java e acontece toda vez que um método chama outro para executar.

O funcionamento desse tipo de chamada, por sua vez, pode ser explicado através do conceito de pilha de execução ou stack da thread.

Cada vez que um método é chamado, suas variáveis, parâmetros e classes são empilhados e, uma vez que esse mesmo método chega ao final de sua execução, esses objetos que foram empilhados são desempilhados, passando a execução ao método chamador, ou seja, ao método que estava na posição inferior da pilha.

Na Figura 1 apresentamos uma representação gráfica de como funciona a pilha de execução de métodos síncronos.

Conforme podemos observar, o exemplo em funcionamento é baseado em três métodos. O primeiro deles, o método main(), começa sua execução ao iniciar a thread e é colocado na pilha. Sua execução continua até a chamada do metodoA(), quando o processo do método main() é interrompido, o metodoA() é colocado no topo da pilha (neste caso, uma posição acima) e inicia seu processamento.

Figura 1. Exemplo do funcionamento da pilha de execução.

Ao chamar o metodoB(), o metodoA() também tem sua execução interrompida, dando início à execução do metodoB(), que, no estado atual do exemplo descrito, é o método que está ocupando o processador.

Por fim, analisando o exemplo da figura, é fácil perceber que sempre o método no topo da pilha é o que está sendo executado pela JVM, enquanto os outros ficam aguardando o fim da execução dos métodos acima. Também é interessante ressaltar que, para cada thread, a JVM cria uma pilha de execução, ou seja, podemos ter múltiplas threads rodando em paralelo dentro de nossa JVM."

[...] continue lendo...

Artigos relacionados