Lista de objetos + Threads

Boa tarde,

É a primeira vez que posto. Já acompanho o fórum faz um tempo e tenho conseguido sanar várias dúvidas que possuía…

Estava realizando alguns testes com threads para verificar se conseguiria otimizar tempo de processamento antes de aplicá-los em um projeto maior.

Nestes teste utilizei duas classes. Uma delas (Programa.java) possui uma função que é basicamente um for, que vai de 0 à 1000000000 (só para matar tempo de processamento), e outra classe (semparalelismo.java) que monta uma lista com objetos instanciados pela classe mencionada anteriormente, e executa a função um à um nos objetos dessa lista montada.

O que eu gostaria de fazer, é tendo uma lista de 3000 objetos, lançar 4 threads, que executariam esta função.

Programa.java

[code]package paralelismo1;

/**
*

  • @author alexandre
    */
    public class Programa implements Runnable {

private int id;
private int valor;

public int getValor(){
    return valor;
}

public int getId() {
    return id;
}


public void setId(int id) {
    this.id = id;
}

@Override
public void run () {
for (int i = 0; i < 1000000000; i++) {
valor++;
}
}
}
[/code]

semparalelismo.java

[code]package paralelismo1;

import java.util.ArrayList;
import java.util.List;

/**
*

  • @author alexandre
    */
    public class semparalelismo {

    public static void main(String[] args) {
    List ListaProgramas = new ArrayList();
    Programa programa;

     long tempoInicio = System.currentTimeMillis();    
    
     for (int i = 1; i < 3002; i++){
         programa = null;
         programa = new Programa();
         programa.setId(i);
         ListaProgramas.add(programa);
     }
    
     for (int i = 1; i < 3001; i++){
         ListaProgramas.get(i).run();
     }
     System.out.println("Tempo Total: "+(System.currentTimeMillis()-tempoInicio)/1000.0+" segundos");         
    

    }
    }
    [/code]

semparalelismo.java executa em aproximadamente 130 segundos.

paralelismovariavel.java

[code]package paralelismo1;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
*

  • @author alexandre
    */
    public class paralelismovariavel {

    public static void main(String[] args) {
    List ListaProgramas = new ArrayList();
    Programa programa;

     Scanner ler = new Scanner(System.in);
    
     int max_programas = 3000;
     max_threads = 4; 
    
     int threads_processadas = 0;
    
     long tempoInicio = System.currentTimeMillis();
     
     for (int i = 0; i <= max_programas; i++){
         programa = null;
         programa =  new Programa();
         programa.setId(i+1);
         ListaProgramas.add(programa);
     }
     
     Thread thread;
     
     do{
         List<Thread> ListaThreads = new ArrayList<Thread>();
         int i = 0;
         do{
             thread = null;
             thread = new Thread(ListaProgramas.get(i));
             ListaThreads.add(thread);
             i++;
         }while((i < max_threads) && (threads_processadas < ListaProgramas.size()));
    
         int e = 0;
         do{
             ListaThreads.get(e).start();
             threads_processadas++;
             e++;
         }while((e < i) && (threads_processadas < ListaProgramas.size()));
    
         try  
         {  
             int o = 0;
             do{
                 ListaThreads.get(o).join();
                 o++;
             }while((o < i) && (threads_processadas < ListaProgramas.size()));
    
         } 
         catch(InterruptedException erro)  
         {  
             System.out.println("Erro: "+ erro);  
         }
         ListaThreads = null;
    
     }while(threads_processadas < ListaProgramas.size());
     
    System.out.println("Tempo Total: "+(System.currentTimeMillis()-tempoInicio)/1000.0+" segundos");       
    

    }

}
[/code]
paralelismovariavel.java executa em proximadamente 70 segundos.

Porém, quando utilizo a estrutura contida em paralelismovariavel.java no projeto que estou trabalhando, que é uma classe bem maior e mais complexa que Programa.java, a execução chega a ficar até 4 vezes mais demorada do que a forma sequencial, executando a função que preciso um à um no objetos da minha lista.

O que estou fazendo de errado? (Não sei se consegui ser claro o bastante)

Qqr ajuda é bem vinda.

Olá alexandrebsilva, primeira coisa, utilize as convenções do Java, por exemplo no nome da sua classe, o padrão é PascalCase, ou seja começa com letra maiúscula e as próximas palavras também são maiúsculas, pra variáveis, utilize o CamelCase ex: ‘ClasseQualquer’, começa com minúscula e termina com maiúscula, ex: ‘variavelUm’.

Tente deixar seu código mais enxuto, deixe o mais claro possível, quanto menos código usar pra fazer a mesma coisa melhor.

Outro ponto foi que você não iniciou nenhuma Thread em seu programa, apenas invocou o método run(), pra iniciar uma Thread é necessário invocar o método start().

[quote=rafadelnero]
Outro ponto foi que você não iniciou nenhuma Thread em seu programa, apenas invocou o método run(), pra iniciar uma Thread é necessário invocar o método start().[/quote]

Opa! Tem sim: ListaThreads.get(e).start();

Alexandre, dá uma verificada em arquitetura produtor-consumidor e em Executor, sua rotina vai ficar muito mais rápida. Alocar e desalocar threads tem um custo.

[quote=A H Gusukuma]
Opa! Tem sim: ListaThreads.get(e).start();

Alexandre, dá uma verificada em arquitetura produtor-consumidor e em Executor, sua rotina vai ficar muito mais rápida. Alocar e desalocar threads tem um custo.[/quote]

Bom dia,

Obrigado pelas pelas respostas rafadelnero e A H Gusukuma

A H Gusukuma, você esta falando em Pools de threads?
Pior que acabei notando que alocar e desalocar threads tem um custo significativo no que eu estou tentando fazer…

Abraços!!!

Sim.