1

I'm new to multithreading. I need to calculate integral by partial sums using multiple threads. I want to find out if all threads finished calculating to show general sum, I'm doing it using sleep(500) but it's stupid. How can i do it by the right way?

public class MainClass {
    private static int threadCount=10;
    public static double generalSum=0;
    private static ArrayList<CalculatingThread> threads;
    public static  void main(String[] args){
        Calculator.setA(0);
        Calculator.setB(2);
        Calculator.setN(500);
        threads=new ArrayList<CalculatingThread>();
        int div=500/threadCount;
        for (int i=0; i<div;i++){
            CalculatingThread thread=new CalculatingThread();
            thread.setJK(i*10,(i+1)*10-1);
            thread.start();
            threads.add(thread);
        }
        try {
            Thread.currentThread().sleep(500);
            System.out.println(generalSum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class CalculatingThread extends Thread {
    private int j;
    private int k;

    @Override
    public void run(){
        System.out.println("Partial sum: " + Calculator.calcIntegral(j, k));
        Calculator.addToSumm(Calculator.calcIntegral(j, k));
        //this.notify();
    }

    public void setJK(int j,int k) {
        this.j = j;
        this.k=k;
    }
}


public class Calculator {
    private  static double a;
    private  static double b;
    private  static int n;

    private static double InFunction(double x){
        return Math.sin(x);
    }
    private double sum=0;

    public static void setA(double a) {
        Calculator.a = a;
    }

    public static void setB(double b) {
        Calculator.b = b;
    }

    public static void setN(int n) {
        Calculator.n = n;
    }

    public static double calcIntegral(int j,int k)
    {
        double result, h;
        int i;

        h = (b-a)/n; //Шаг сетки
        result = 0;

        for(i=j; i <= k; i++)
        {
            result += InFunction(a + h * i - h/2); //Вычисляем в средней точке и добавляем в сумму
        }
        result *= h;
        return result;
    }

    public static synchronized void addToSumm(double sum){
        MainClass.generalSum+=sum;
    }
}

P.S. sorry, i know code is stupid, i will refactor it later

JenyaKirm
  • 57
  • 1
  • 5

2 Answers2

1

Replace

Thread.currentThread().sleep(500);

with

for (Thread thread : threads) {
    thread.join();
 }

This will make main thread to wait until all the created threads get completed. Also you can refer wait until all threads finish their work in java

Community
  • 1
  • 1
Sangeeth
  • 614
  • 1
  • 5
  • 14
0

you can use join to make the main thread wait for the others:

The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,

t.join(); causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

save every thread you create in an array and then do join on them

so your main should look like

public class MainClass {
    private static int threadCount=10;
    public static double generalSum=0;
    private static ArrayList<CalculatingThread> threads;
    public static  void main(String[] args){

        Calculator.setA(0);
        Calculator.setB(2);
        Calculator.setN(500);
        threads=new ArrayList<CalculatingThread>();
        int div=500/threadCount;
        for (int i=0; i<div;i++){
            CalculatingThread thread=new CalculatingThread();
            thread.setJK(i*10,(i+1)*10-1);
            thread.start();
            threads.add(thread);
        }
        try {
            for (Thread curr: threads) {
               curr.join();
            }

            System.out.println(generalSum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

now on a side note, no series program is using sleep when it wants to wait. sleep is only used when you actually need a delay in a background thread

P.S. do not refactor the code. it is excellent to post it like that, so i can see every mistake you do if u do. a lot better then most people posting only 1 line and then there is nothing i can do but ask for more details

No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
  • thanks for good advice. i used notify and wait, but now i know two ways how to do it. What i meant saying that my code is bad - is that i used a lot of static variables - i think it's not right – JenyaKirm Nov 10 '14 at 10:47
  • @JenyaKirm might be, but unless there is something completely wrong in your program, i doubt anyone will say anything – No Idea For Name Nov 10 '14 at 10:49
  • @JenyaKirm btw, if you solved it in any other way you should write an answer for future programers – No Idea For Name Nov 10 '14 at 10:50