Loop para criar Thread e CPU indo nas alturas

6 respostas
usphisics

Fala povo, estou tendo um problema e gostaria de compartilhar com o pessoal que entende tudo de thread.

Tenho uma aplicação na qual preciso realizar muitas ‘tarefas’, mas muitos. Para tal eu tenho o seguinte código (± pois algumas coisas foram omitidas).

ExecutorService es = Executors.newFixedThreadPool(threadSize);
    
	do{
        
		Long cod = nextCodService();
		
		if(cod != null){
			
			MinhaClasseRunnable minhaThread = new MinhaClasseRunnable(cod);
			es.submit(minhaThread);
			
			Thread.Sleep(50);
			
		}else{
			Thread.Sleep(1000);
		}
			
	}while(true);

Dentro da classe MinhaClasseRunnable tem um trecho de código que também usa Thread pois preciso setar um TimeOut para a thread:

...

                ExecutorService es = Executors.newSingleThreadScheduledExecutor();
		MinhaClasseCallable minhaThread = new MinhaClasseCallable(urlParse);
		Future<String> future = es.submit(minhaThread);
		es.shutdown();

		String page = future.get(60, TimeUnit.SECONDS);
		
                ...

Bom a idéia ter um pool de threads para ir usando conforme o doWhile vai criando as threads…
No segundo trecho de código eu crio um Thread (interna) a que foi lançada pois em alguns casos o tempo para finalizar uma thread pode ser grande (+2min, o normal é cerca de 10sec) e fique com medo de por exemplo setar ThreadSize com 20 e ter o azar de em determinado momento da execução ter as 20 threads aguardando (2min) para serem finalizadas e ainda ter muitos trabalhos ainda para serem tratados pelas threads… hehehhe isso realmente aconteceu quando eu não tinha essa thread interna.

Bom o que acontece é o seguinte:
O código em si funciona legal porém tenho 2 micros um ± e outro ± para -, hehehehe…No ± a CPU dá uma subida no inicio mas depois vai abaixando com o tempo e fica estável. No segundo que é um pouco inferior (não muito) a CPU fica colada em 100% o tempo todo…
Para vocês terem uma idéia eu cortei a quantidade de ThreadSize pela metade e ainda assim continua com CPU alta…o problema é que eu sei que esse micro agüentaria sim a quantidade de Thread normal ainda mais dividido pela metade.

Eu desconfio que a forma como as Threads são criadas, uma atrás da outra é que estão afetando esse micro, como está chegando várias Threads ao mesmo tempo, a CPU fica mais tempo tentando trocar uma thread pela outra do que realmente trabalhando…Talvez a Thread interna acabe por dobrar a quantidade total de Threads no sistema ao mesmo tempo, afinal para cada Thread externa (principal) eu tenho uma interna mesmo que na maioria das vezes elas rodem rápido (cerca de 10sec).

O que vocês acham ???

Até +

6 Respostas

E

MinhaClasseRunnable herda de Thread ou é simplesmente uma classe simples, que implementa Runnable?

E

MinhaClasseRunnable herda de Thread ou é simplesmente uma classe simples, que implementa Runnable?
nextCod() é um método que bloqueia se não houver mais códigos disponíveis para serem processados?

usphisics

Opa,

Implementa somente Runnable e o o serviço que me dá esse próximo código retorna null quando não tem mais código daí a thread que roda no loop dorme alguns segundos e depois passa novamente a pedir por código pois esses códigos de tempos em tempos vão ser recriados e daí preciso voltar a rodar tudo novamente.

Uma coisa que acabei de me atentar e é uma dúvida muito básica é:

dentro do loop eu pego uma thread do pool quando dou um submit e vou embora para pegar outra thread…até ai blz…Mas o que acontece quando essa primeira thread termina de fazer o que tem que fazer ??? Para mim como ela é Runnable ela não tem retorno e por isso morre, o que me deixa feliz pois a mesma não continuaria abaixo no loop e tentaria ela fazer loop… É isso mesmo ??? Por que senão daí tenho um problema correto, vou ter as thread voltando e também continuando no loop e para evitar isso precisaria finalizar as thread ainda dentro do método run() delas correto ?

obs: não tenho mais aquela Thread interna pessoal, dei um jeito de evitar a utilização da mesma…

Até +

E

Vou explicar o que é feito em um pool de threads.
Tire essa idéia fixa de “thread” da cabeça e pense em um Executor.
(Eu ainda acho que usar threads diretamente em código é a mesma coisa que usar “goto” em programas - devia ser proibido, mas não vou ficar insistindo muito nisso).

Imagine que você tem 10 tarefas, cada qual demorando 2 dias, e você tem 4 pessoas para executarem essas tarefas. Imagine que cada pessoa possa executar apenas uma tarefa de cada vez.
Como você tem 4 pessoas, você pode executar até 4 tarefas ao mesmo tempo.
Se uma pessoa terminar sua tarefa, ela não morre nem é demitida, só espera receber mais uma tarefa.

Troque as palavras “tarefa”, “pessoa” por “task” (pode ser um Runnable ou um Callable) e “thread”. No seu caso, você criou um newFixedThreadPool e você contratou threadSize pessoas. Quando você chama “execute”, você passou um Runnable ou um Callable a uma pessoa para ser executada. Quem é essa pessoa? A que estiver desocupada (ou seja, a que terminou a task anterior) antes.

Se você usar outros tipos de executors, terá políticas diferentes. Por exemplo, um newCachedThreadPool começa com 1 pessoa contratada, mas vai contratando mais à medida que vai precisando. Um newFixedThreadPool contrata exatamente N pessoas. Um newSingleThreadExecutor contrata exatamente uma pessoa (e nunca contrata mais que essa pessoa). Um newScheduledThreadPool é especial porque ele trabalha com tarefas periódicas.

Leia com atenção: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executors.html

usphisics

Valeu,
É vi que eu ± que estava pensando corretamente…
Também um programinha besta somente para ter certeza…

Estou tentando fazer uns ajustes para conseguir diminuir o consumo de CPU na máquina…se conseguir eu posto aqui…

Até +

usphisics

Uma coisa que não falei pessoal é que tenho uma versão da aplicação em C# que faz a mesma coisa, absolutamente a mesma coisa inclusive da mesma maneira…na versão do C# eu rodo nesse micro 80 thread e a CPU fica perto dos 100% mas não os 100%…digo 80% a 90%…já a versão em Java com 10 threads consume 100% da CPU 100% do tempo …

Alguma idéia galera…

Read more: http://javafree.uol.com.br/topic-888321-Criacao-de-Thread-em-Loop-e-CPU-indo-nas-alturas.html#ixzz2ECfy0Kxj

Criado 4 de dezembro de 2012
Ultima resposta 5 de dez. de 2012
Respostas 6
Participantes 2