Artigo do tipo Exemplos Práticos
Recursos especiais neste artigo:
Conteúdo sobre Novidades
Porque este artigo é útil
Com computadores cada vez mais avançados e com mais processadores, é fundamental que as aplicações sejam capazes de tirar o melhor proveito possível de todo esse poder de processamento. Para tal, é indispensável que arquitetos e desenvolvedores conheçam a fundo quais alternativas existem na plataforma Java para a execução paralela de aplicativos. Este artigo dará uma visão geral sobre a nova especificação de concorrência presente no Java EE 7, mostrando a API através de exemplos práticos. Deste modo, ele ajudará tanto os leitores que estão buscando conhecer as novidades do Java EE 7 quanto os que estão procurando entender um pouco mais sobre processamento paralelo no Java, principalmente em sistemas Java EE.

Assim que a Oracle anunciou a compra da Sun em 2009, a especulação sobre qual seria o futuro da plataforma Java tomou conta da comunidade, através de fóruns, blogs e artigos. A maioria estava receosa sobre qual direcionamento seria dado à plataforma, tanto em termos de licenciamento quanto em termos de evolução e de participação da comunidade nas decisões a serem tomadas. Porém, um pouco mais de quatro anos após esse anúncio, o que vemos é que a comunidade está até mais presente e mais forte no JCP, com programas de incentivo de participação como o “Adopt a JSR” e com convites a grupos de usuários Java, como aconteceu com o brasileiro SouJava, mostrando a força da comunidade brasileira.

Outro ponto a ser observado é no que diz respeito à liberação de novas versões da plataforma, que tem seguido um ritmo acelerado e baseado em um roadmap mais bem definido. A maneira como a plataforma Java EE tem evoluído nos últimos anos é notável, principalmente no que diz respeito à maior simplicidade de uso. Este sempre foi um requisito bastante solicitado pela comunidade como um todo e que começou a ser atendido no Java EE 5, tendo sequência na versão 6 e agora na 7.

Além do foco em maior simplicidade, essas novas versões trouxeram várias melhorias e novos recursos. Com o Java EE 7 não foi diferente, uma vez que essa versão traz melhorias em várias especificações existentes, como EJB, JMS e JSF, apenas para nomear algumas. Além disso, introduziu novas especificações, tais como Batch Applications for the Java Platform e Concurrency Utilities for Java EE. Neste artigo em particular, vamos abordar essa última, mostrando uma visão geral da API e apresentando alguns exemplos.

Concurrency Utilities for Java EE

Uma das várias vantagens de se utilizar um servidor de aplicações Java EE é a de deixar que este faça o gerenciamento de recursos, tirando essa responsabilidade da aplicação. O exemplo mais tradicional disso é quanto ao uso do pool de conexões com um Banco de Dados. Dado essa característica, a especificação do Java EE sempre foi bastante enfática ao dizer que as aplicações Java EE deveriam usar o próprio container para o gerenciamento de alguns recursos, como por exemplo, criação e gerenciamento de threads.

As boas práticas sempre disseram que aplicações Java EE não deveriam criar threads de forma manual. A fim de se realizar processamento paralelo, existiam basicamente duas formas: JMS e EJBs assíncronos. Apesar de sistemas de mensageria serem extremamente eficientes, em alguns casos eles são muito complexos para o problema a ser resolvido, trazendo uma complexidade indesejável para a solução. Os EJBs assíncronos – através da anotação @asynchronous e de timers – são um pouco mais simples de serem utilizados, mas também não fornecem uma API flexível o bastante. Por outro lado, no mundo Java SE já existia uma API bastante interessante para processamento assíncrono, como o ExecutorService, o que deixou claro que o mundo EE precisava de algo similar.

Outro problema que a falta de uma especificação como essa causava no Java EE se dá em relação à integração com frameworks externos. Spring, Quartz, EhCache e muitos outros precisam ter suas threads rodando em background. Como não existia uma forma de se usar as threads criadas pelo container, eles eram obrigados a criar suas próprias threads manualmente.

Com o intuito de resolver essas questões, a Java EE 7 trouxe uma especificação para esse fim: a JSR 236 – Concurrency Utilities for Java EE. Ela é bem parecida com a presente no Java SE e, na verdade, muitas das classes e interfaces adicionadas implementam ou estendem interfaces ou classes presentes no Java SE, fornecendo uma API bastante parecida com a que os desenvolvedores estão acostumados. Além de dar maior flexibilidade a esses, essa API também visa facilitar e melhorar a forma como frameworks se integram à plataforma Java EE e ao container.

Visão geral da API

Conforme apresentado na seção anterior, a API de Concurrency Utilities é bem parecida com a do Java SE. Essa nova API provê basicamente três interfaces principais: ManagedExecutorService, ManagedScheduledExecutorService e ManagedThreadFactory. A Figura 1 mostra uma visão de alto nível do relacionamento dessas interfaces com as existentes no Java SE.

abrir imagem em nova janela

Figura 1. Visão geral da API Concurrency Utilities.

É a partir dessas interfaces que se torna possível criar, executar e agendar a execução de tarefas assíncronas. Além dessas interfaces, a especificação também fornece outras interfaces e classes, tais como: ManagedTask, Trigger, ManagedTaskListener e ManagedExecutors. No decorrer do artigo serão apresentadas mais informações sobre essas interfaces e classes.

Colocando a mão na massa

A fim de apresentar a API de forma mais detalhada, iremos agora criar alguns exemplos práticos, exercitando algumas das interfaces e classes disponibilizadas. Para facilitar a invocação do código pelo usuário, os exemplos serão inseridos em uma aplicação web através de Servlets. Como servidor de aplicação, adotaremos o GlassFish 4.0, que é a implementação de referência do Java EE 7 e já oferece suporte completo ao mesmo. Como ferramenta de desenvolvimento e integração com o GlassFish, será adotada a versão mais recente do Eclipse, com o codinome Kepler, que também já conta com suporte ao Java EE 7.

Configurando o ambiente

A configuração de nosso ambiente começa com a instalação do plugin do GlassFish no Eclipse. Para isso, vá até o menu Help > Eclipse Marketplace e pesquise por “GlassFish”. Na lista de resultados, instale o plugin GlassFish Tools for Kepler. Como de costume, é necessário reiniciar o Eclipse após o término da instalação. Para configurar o GlassFish no Eclipse, selecione a opção Server a partir do menu File | New > Other > Server > Server e clique em Next. Feito isso, escolha o servidor GlassFish 4.0 e avance para a próxima etapa usando Next. Nessa tela temos a opção de usar um servidor GlassFish já instalado na máquina ou de solicitar ao Eclipse para fazer o download automaticamente. Para a primeira opção basta colocar o caminho do servidor no campo Glassfish Server Directory. Caso prefira que o Eclipse faça o download para você, coloque nessa mesma propriedade o caminho no qual o servidor deve ser instalado e clique em Install Server ...

Quer ler esse conteúdo completo? Tenha acesso completo