Foi adicionada esse pacote para facilitar  aplicações que necessitem escalar ou realizar processos em paralelos.

            Umas das melhorias são as variáveis atômicas, uma variável atômica é que não pode ser dividida, é semelhante ao Sistema operacional que possui um recurso (um leitor usb, por exemplo) que não pode ser dividido, no entanto pode ser usado por vários processos ao mesmo tempo. Na listagem 11 é mostrado um exemplo simples de produtor e consumidor em que uma variável atômica é utilizada entre os dois processos.

 


           static class AtomicCounter {

         private AtomicInteger contador = new AtomicInteger(0);

         public void increment() {

             System.out.println("Incrementando " + contador.incrementAndGet());
         }
 
         public void decrement() {
             System.out.println("Decrementando " + contador.decrementAndGet());
 
         }
 
         public int value() {
             return c.get();
         }
     }
 
     static class Produtor implements Runnable {
 
         private AtomicCounter atomicCounter;
 
         public Produtor(AtomicCounter contador) {
             this.atomicCounter = contador;
 
 
         }
 
         @Override
         public void run() {
             while (true) {
 
                 try {
                     Thread.sleep(2000);
                 } catch (InterruptedException ex) {
                     ex.printStackTrace();
                 }
                 atomicCounter.increment();
 
 
             }
         }
     }
 
     static class Consumidor implements Runnable {
 
         private AtomicCounter atomicCounter;
 
         public Consumidor(AtomicCounter contador) {

            this.atomicCounter = contador;
 
 
         }
 
         @Override
         public void run() {
             while (true) {
 
                 try {
                     Thread.sleep(4000);
                 } catch (InterruptedException ex) {
                     ex.printStackTrace();
                 }
                 atomicCounter.decrement();
 
             }
         }
     }
 
     public static void main(String[] args) {
 
         AtomicCounter atomicCounter = new AtomicCounter();
         Thread consumidor = new Thread(new Consumidor(atomicCounter));
         Thread produtor = new Thread(new Produtor(atomicCounter));
         consumidor.start();
         produtor.start();
         while (true) {
         }
 
     }


Listagem11: exemplo simples de consumidor e produtor usando variável atômica

 

            É possível usar variáveis atômicas a partir de uma classe para isso basta que essa implemente o java.io.Serializable


    public static void main(String[] arg) {

         AtomicReference meubojeto = new AtomicReference<>();

         System.out.println(meubojeto.get());//imprime nulo

         meubojeto.set(new MeuObjeto("valor Atributo"));

         System.out.println(meubojeto.get().getAtributo());//imprime valor Atributo

         AtomicReferenceArray usuarios = new AtomicReferenceArray(10);

         // array atomico com o tamanho 10      

         usuarios.getAndSet(1, new MeuObjeto("Setando objeto 1"));

 

     }


Listagem 12: criando variáveis atômicas e array de Objetos criados

 

A partir desse novo jdk existem novas coleções concorrentes.


   BlockingDeque fila = new LinkedBlockingDeque<>();

   ConcurrentMap mapa = new ConcurrentHashMap();

 ConcurrentNavigableMap maps = new ConcurrentSkipListMap<>();


Listagem 13: Collections concorrentes

 

            Com a concorrência de processos pode-se bloquear um  recurso impedindo que uma Thread acesse durante aquele momento para isso basta usar a classe java.util.concurrent.locks.Lock.

 

             O Executor tem como principal objetivo realizar processos paralelos de grande escala, nele é possível implementar três novas interfaces (Executor, ExecutorService, ScheduledExecutorService) para concorrência além da maioria das classes do pacote executam no pool de Threads, garantindo uma maior eficiência no gerenciamento de processos concorrentes dentro da jvm. Outro recurso é o Fork/Join que implementa a interface ExecutorService que ajuda a tirar proveito de múltiplos processamento, processos que possam ser divididos em menores e trabalhem de forma recursiva.

 

 

Conclusão:

 

 

Neste artigo foi abordado sobre as novidades da parte de concorrência do java 7, a pasta current, trouxe várias novidades para facilitar os processos paralelos.