sexta-feira, 8 de abril de 2011

Pool de Threads


Um pool de threads é uma coleção de threads disponíveis para realizar tarefas
Pools geralmente provêem:


Melhor performance quando se executam um grande número de tarefas devido a um overhead reduzido de chamadas por tarefa;


Uma forma de limitar recursos consumidos (incluindo threads) ao executar uma coleção de tarefas;


Um programa com milhares de threads pode sofrer em desempenho


Adicionalmente, com um pool de threads, você não precisa preocupar-se com o cilclo de vida dos threads (criação, destruição)


Você pode se concentrar em criar business logic em vez de gerenciar threads
Para usar pools de threads, instancie uma implementação da interface ExecutorService e entregue tarefas para execução


Duas implementações da interface:


ThreadPoolExecutor
ScheduledThreadPoolExecutor


As implementações permitem que você estabeleça:


O número básico e máximo do pool (número de threads)


O tipo de estrutura de dados para armazenar as tarefas


Como tratar tarefas rejeitadas


Como criar e terminar threads


Porém, é melhor criar pools usando od factory methods da classe Executors (ver tabela)


Os métodos acertam a configuração do pool para os casos mais típicos


Factory Methods na classe Executors


Método Descrição


newFixedThreadPool(int) Cria um pool com número fixo de threads e fila 



ilimitada de tarefas

newCachedThreadPool Cria um pool de threads sem limite, com recuperação 



automática de threads (threads que já terminaram as tarefas são reutilizados 
para novas tarefas e novos threads são criados só se não houver thread "velho" disponível)

É uma boa opção quando há muitas tarefas pequenas a executar assincronamente.

Threads não usados por 60 segundos são removidos

newSingleThreadExecutor Cria um thread único em background com fila ilimitada de tarefas


As tarefas serão executadas sequencialmente

Abaixo está uma tarefa WorkerThread que será executada por um thread
A tarefa faz algo e periodicamente informa o percentual de trabalho realizado


public class WorkerThread implements Runnable {
private int workerNumber;

WorkerThread(int number) {
workerNumber = number;
}

public void run() {
for (int i=0;i<=100;i+=20) { // Perform some work ... System.out.println("Worker number: " + workerNumber + ", percent complete: " + i ) try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } } }


Em ThreadPoolTest especificamos o número de "worker threads" (tarefas) a criar e o tamanho do pool de threads usados para executar as tarefas

O exemplo usa um número fixo de threads e com menos threads do que tarefas

<code>
import java.util.concurrent.*;
public class ThreadPoolTest {
public static void main(String[] args) {
int numWorkers = Integer.parseInt(args[0]);
int threadPoolSize = Integer.parseInt(args[1]);

ExecutorService tpes =
Executors.newFixedThreadPool(threadPoolSize);

WorkerThread[] workers = new WorkerThread[numWorkers];
for (int i = 0; i < numWorkers; i++) { workers[i] = new WorkerThread(i); tpes.execute(workers[i]); } tpes.shutdown(); } } 



</code>Execução do teste com 4 tarefas e um pool com 2 threads: 

java ThreadPoolTest 4 2 Worker number:
 0, percent complete: 0 Worker number: 1, 
percent complete: 0 Worker number: 0, 
percent complete: 20 Worker number: 0, 
percent complete: 40 Worker number: 1, 
percent complete: 20 Worker number: 0, 
percent complete: 60 Worker number: 0, 
percent complete: 80 Worker number: 0, 
percent complete: 100 Worker number: 1, 
percent complete: 40 Worker number: 1, 
percent complete: 60 Worker number: 2, 
percent complete: 0 Worker number: 1,
 percent complete: 80 Worker number: 2, 
percent complete: 20 Worker number: 2, 
percent complete: 40 Worker number: 1, 
percent complete: 100 Worker number: 2, 
percent complete: 60 Worker number: 2, 
percent complete: 80 Worker number: 2, 
percent complete: 100 Worker number: 3, 
percent complete: 0 Worker number: 3, 
percent complete: 20 Worker number: 3, 
percent complete: 40 Worker number: 3, 
percent complete: 60 Worker number: 3,
 percent complete: 80 Worker number: 3,
 percent complete: 100 



Observe como as tarefas 0 e 1 foram alocadas ao 2 threads e rodam até terminar


Só depois disso é que as tarefas 2 e 3 podem ser alocadas a threads e iniciar

WorkerThread implementa a interface Runnable

Também podemos implementar a interface Callable como em callableWorkerThread abaixo


Callable é mais flexível que Runnable pois pode retornar um valor lançar uma exceção


import java.util.concurrent.*;
public class CallableWorkerThread implements Callable {
private int workerNumber;

CallableWorkerThread(int number) {
workerNumber = number;
}

public Integer call() {
for (int i = 0; i <= 100; i += 20) { // Perform some work ... System.out.println("Worker number: " + workerNumber + ", percent complete: " + i ); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } return(workerNumber); } }

ThreadPoolTest2 usa o executor CachedThreadPool que cria quantos threads forem necessários mas reutiliza threads quando uma tarefa termina
O método submit() pede a um executor para rodar um Callable
O método retorna um objeto do tipo Future que permite controlar a tarefa
Com o objeto Future podemos receber o resultado da tarefa, monitorar a tarefa e cancelar a tarefa
Por exemplo, para receber o valor retornado pela tarefa:
public class ThreadPoolTest2 {
public static void main(String[] args) {
int numWorkers = Integer.parseInt(args[0]);

ExecutorService tpes =
Executors.newCachedThreadPool();
CallableWorkerThread workers[] =
new CallableWorkerThread[numWorkers];
Future futures[] = new Future[numWorkers];

for (int i = 0; i < numWorkers; i++) { workers[i] = new CallableWorkerThread(i); futures[i]=tpes.submit(workers[i]); } for (int i = 0; i < numWorkers; i++) { try { System.out.println("Ending worker: " + futures[i].get()); } catch (Exception e) {} } } }

Eis o resultado
Observe como cada tarefa inicia imediatamente
Quando a tarefa termina, ela retorna seu número que é obtido através do objeto Future
% java ThreadPoolTest2 4
Worker number: 0, percent complete: 0
Worker number: 1, percent complete: 0
Worker number: 2, percent complete: 0
Worker number: 3, percent complete: 0
Worker number: 3, percent complete: 20
Worker number: 3, percent complete: 40
Worker number: 3, percent complete: 60
Worker number: 1, percent complete: 20
Worker number: 0, percent complete: 20
Worker number: 1, percent complete: 40
Worker number: 2, percent complete: 20
Worker number: 3, percent complete: 80
Worker number: 0, percent complete: 40
Worker number: 2, percent complete: 40
Worker number: 2, percent complete: 60
Worker number: 1, percent complete: 60
Worker number: 3, percent complete: 100
Worker number: 2, percent complete: 80
Worker number: 2, percent complete: 100
Worker number: 0, percent complete: 60
Worker number: 0, percent complete: 80
Worker number: 0, percent complete: 100
Worker number: 1, percent complete: 80
Ending worker: 0
Worker number: 1, percent complete: 100
Ending worker: 1
Ending worker: 2
Ending worker: 3

Twiter Agora será em java!

Fala galera!
Veja esta novidade de nosso amigo Twiter...Ele terá java no lugar do Ruby. Veja a Notícia:

No final de outubro de 2010, o Twitter começou a desenvolver um novo mecanismo de busca em tempo real que traria muitos benefícios, entre eles: melhora de desempenho, redução do tempo de resposta (ou latência), suporte a desenvolvimento de novas funcionalidades de pesquisa, maior disponibilidade e ? principalmente ? suporte ao crescimento exponencial de usuários do serviço. E na semana passada foi finalizada uma mudança de grande impacto nesta área: a troca dos componentes de "front-end", que recebem as requisições das aplicações no lado do cliente (vindas do Twitter.com, widgets, aplicações móveis etc.). O novo front-end, batizado de Blender e criado em Java, substituirá totalmente a antiga implementação em Ruby on Rails. 

A mudança do front-end gerou efeito muito significativo: foi reduzida em três vezes a latência média das buscas. Segundo a equipe do Twitter, na época do Tsunami no Japão e antes da disponibilização do Blender, o alto volume de pesquisas aumentou a latência consideravelmente. Em um momento de pico, pesquisas por #tsunami, por exemplo, chegaram a demorar 800 milissegundos para mostrar resultados. Já com o uso do Blender, o tempo de resposta em condições similares de carga caiu para 250ms. 

segunda-feira, 4 de abril de 2011

Personalizando Tela Principal




Fala Galera!!! Eu Bruno Rafael Venho aqui desta vez postar-lhes uma Video aula de como Personalizar a tela inicial de sua aplicação deixando ela de uma forma mais simpática!!

Admin: Bruno

Olá Galera! muito grato por estarem acessando nosso blog. Espero que seja possível transmitir de forma compreensível um pouco de meus conhecimentos em programação, para esta comunidade de desenvolvedores que cresce cada vez mais! Espero que Gostem! Abraço! E meu enorme obrigado à Renato Simões, Átila Soares,Wanderson Quinto, Emerson e a toda galera que sempre ajudou meu sincero obrigado....
Especialmente a Natalia Failache e Rita de Cassia que sempre apoiaram este sonho....

De seu amigo Bruno Rafael.