Este é um post disponível para assinantes MVPArtigo Java Magazine 20 - Byte Code
Artigo publicado pela Java Magazine 20.
Byte Code
Concorrência no Java 5
A nova API do Tiger para Multithreading
As novidades do pacote java.util.concurrent revolucionam o desenvolvimento de aplicações trazendo capacidades espantosas de execução concorrente
Programação Concorrente (PC) é um recurso fundamental do Java. Existe desde a versão 1.0, teve pouquíssimas mudanças até o J2SE 1.4 e é uma das partes mais simples e estáveis da plataforma. A classe Thread cria contextos de execução concorrentes; todos os objetos têm monitores úteis para notificação e exclusão mútua (facilitada pela sintaxe synchronized); e o modificador volatile evita problemas com variáveis acessadas sem sincronização por múltiplos threads. Até há pouco, isso resumia tudo o que um programador Java precisava saber em matéria de threads e concorrência.
Ou será que não? A API e os recursos da linguagem podem ser simples, mas a complexidade da programação concorrente não está nas APIs e sintaxes. Está em outro nível. Por exemplo, como evitar deadlocks, tomando cuidado com a ordem de sincronizações; ou como criar um pool de threads; ou ainda como estruturar o código de um componente concorrente para obter o máximo de desempenho, sincronizando somente trechos mínimos de código.
Em muitos casos a simplicidade do modelo de programação concorrente do Java era uma desvantagem. Tínhamos um número muito pequeno de primitivas (threads e monitores) servindo como “pau para toda obra”, sendo às vezes necessário implementar recursos mais especializados sobre estas primitivas. Mas isso não era fácil – e devido às restrições de segurança da JVM, nem sempre podia ser feito com eficiência.
Uma das principais APIs introduzidas pelo J2SE 5.0, a java.util.concurrent (JUC), vem resolver estes problemas, acrescentando muitas novas facilidades de programação concorrente embutidas na plataforma Java. Veremos neste artigo o que fazem e como tirar proveito dessas novas funcionalidades.
Planejamento
Na elaboração deste artigo foi difícil decidir a ordem de exposição dos assuntos. Optei pela seqüência de mais baixo nível para mais alto nível, que evita problemas de dependência, pois os últimos são implementados sobre os primeiros. Por outro lado, os recursos de mais baixo nível são mais “hardcore”, e seu uso direto será mais comum em códigos de infra-estrutura. Os últimos, de mais alto nível, são mais acessíveis e orientados à programação de aplicações. Dependendo da sua familiaridade com técnicas de programação concorrente, pode ser mais fácil começar pelo tópico “Utilitários de alto nível” e depois ler os tópicos anteriores.
Também não houve espaço para uma exposição dos recursos tradicionais de PC do Java – criação de threads e uso de monitores – mas isso não deve ser um problema. A API java.util.concurrent apresenta um modelo quase totalmente independente de programação; você nunca precisará criar ou controlar threads diretamente (os “executores” farão isso com vantagens), e as funcionalidades dos monitores são totalmente substituídas por novas APIs de sincronização que são muito superiores.
Operações atômicas
O pacote java.util.concurrent.atomic oferece objetos que encapsulam todos os tipos primitivos, semelhantes aos wrappers de java.lang (Integer, Double etc.), com a diferença que os objetos da nova API são mutáveis, como mostra o exemplo:
AtomicInteger x = new AtomicInteger(10);
x.set(-5); // x é mutável – a mesma instância agora representa outro valor!
Integer y = new Integer(10);
y = new Integer(-5); // y é imutável – para representar outro valor deve-se criar outra instância
Estas novas classes também não podem substituir totalmente os wrappers tradicionais, como java.lang.Integer, pois o design imutável destas classes também tem suas vantagens. Os wrappers mutáveis não podem ser usados como chaves de Map ou em outras situações onde o comportamento de hashCode() e equals() precise ser estável (veja o artigo “Coleções de ponta a ponta” na Edição 18).
Mas as maiores vantagens das novas classes são seus métodos adicionais, que suportam uma série de operações interessantes com comportamento atômico:
Classes AtomicXXX: Wrappers mutáveis com operações atômicas
"
ATENÇÃO! A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVP
Space do autor



0
0
