Thread em java

8 respostas
R

Olá, preciso fazer um programa em java que some os 1.000.000 primeiros usando threads.Porém em meu programa cada vez que eu rodo ele dá um resultado diferente.

public class naturais {

public static void main(String[] args) {
	
	Calcular c1 = new Calcular(0,125.000);
	Calcular c2 = new Calcular(126.000,150.000);
	Calcular c3 = new Calcular(151.000,300.000);
	Calcular c4 = new Calcular(301.000,425.000);
	Calcular c5 = new Calcular(426.000,550.000);
	Calcular c6 = new Calcular(551.000,675.000);
	Calcular c7 = new Calcular(676.000,800.000);
	Calcular c8 = new Calcular(801.000,1000.000);

	    c1.start();
	    c2.start();
	    c3.start();
	    c4.start();
	    c5.start();
	    c6.start();
	    c7.start();
	    c8.start();

	
	
	System.out.println("Resultado: " + (c1.getResult() + c2.getResult() +c3.getResult()+ c4.getResult()+c5.getResult() +c6.getResult()+c7.getResult()+ c8.getResult()));
}
	
	
}

public class Calcular extends Thread {

private double vi;
private double vf;
private double result;

public Calcular(double vi, double vf) {
this.vi= vi;
this.vf=vf;


Thread t= new Thread(this);
t.start();


}

@Override
public void run() {
	for(double i = vi; i <= vf; i++) {
        result += i;
	System.out.println(i);
		
	}

}

	

@SuppressWarnings("finally")
public double getResult() {
	  try {
	        this.join();
	    } finally {
	        return result;
	    }
}

}

8 Respostas

B

no construtor vc estarta a Thread e depois no main vc está estartando novamente

R

Ops , nem tinha reparado. Deixei somente a do main porém vejo que está somando várias vezes a mesma sequência de números ,por exemplo de 100.000 a 200.000 mas o resultado pelo menos não está mais mutável. Como resolver isso ?

Rodrigo_Sasaki

Se você testa com uma única thread. os resultados saem como você espera em repetidas execuções?

Rodrigo_Sasaki

Reparei agora que você está chamando o join na própria classe Calcular.

O método join tem que ser chamado para bloquear até que outra thread finalize sua execução. Portanto você tem que chamar o join na sua main thread

Rodrigo_Sasaki

Caso te ajude eu resolvi implementar esse problema por diversão. Ele divide o número total em partes iguais. E o número de partes é o número de threads disponíveis na sua máquina:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

class Serie {
    private Integer valorInicial;
    private Integer valorFinal;

    public Serie(final Integer valorInicial, final Integer valorFinal) {
        this.valorInicial = valorInicial;
        this.valorFinal = valorFinal;
    }

    public Integer getValorInicial() {
        return valorInicial;
    }

    public Integer getValorFinal() {
        return valorFinal;
    }

    @Override
    public String toString() {
        return valorInicial + " ~ " + valorFinal;
    }
}

class Soma extends RecursiveTask<Long> {

    private Integer valorInicial;
    private Integer valorFinal;

    public Soma(final Integer valorInicial, final Integer valorFinal) {
        this.valorInicial = valorInicial;
        this.valorFinal = valorFinal;
    }

    protected Long compute() {
        Long soma = Long.valueOf(0);
        for (int i = valorInicial ; i <= valorFinal ; i++) {
            soma += i;
        }
        return soma;
    }
}

public class Main {

    public static void main(String[] args) {
        int threadsDisponiveis = Runtime.getRuntime().availableProcessors();
        System.out.println("Threads Disponiveis: " + threadsDisponiveis);

        final ForkJoinPool forkJoinPool = new ForkJoinPool(threadsDisponiveis);

        List<Serie> series = montarSeries(1, 1000000, threadsDisponiveis);
        System.out.println(series);
        Long soma = series.stream()
                .map(s -> forkJoinPool.invoke(new Soma(s.getValorInicial(), s.getValorFinal())))
                .mapToLong(Long::longValue)
                .sum();

        System.out.println(soma);
    }

    private static List<Serie> montarSeries(final Integer inicio, final Integer fim, final Integer pedacos) {
        List<Serie> series = new ArrayList<>();
        Integer tamanhoPedaco = fim / pedacos;
        Integer valor = inicio;
        while (valor <= fim) {
            Integer fimPedaco = Math.min(valor + tamanhoPedaco - 1, fim);
            series.add(new Serie(valor, fimPedaco));
            valor = fimPedaco + 1;
        }
        return series;
    }
}
R

Então , eu só quero que some tudo e dê o resultado certinho. Fiquei confusa sobre o join , eu posso pegar tudo que está em volta dele e colocar no main também ? ou vou ter que criar do 0?

Rodrigo_Sasaki

Você só tem que chamar o join na mesma thread que deu o start. Exemplo:

c1.start();
	    c2.start();
	    c3.start();
	    c4.start();
	    c5.start();
	    c6.start();
	    c7.start();
	    c8.start();

	    c1.join();
	    c2.join();
	    c3.join();
	    c4.join();
	    c5.join();
	    c6.join();
	    c7.join();
	    c8.join();
R

Ahhhh entendi , vou tentar fazer aqui.

Criado 13 de setembro de 2019
Ultima resposta 14 de set. de 2019
Respostas 8
Participantes 3