H
H
Hello America2014-12-07 09:14:56
Java
Hello America, 2014-12-07 09:14:56

How to loop on a thread in Java/Thread?

Hello. There is a class code that defines the matrix determinant. The algorithm is correct, everything works, but I need to organize the specified for loops in threads:

package determinant;

import java.util.ArrayList;

class  CMatrix{
public double determinant(double A[][],int N) throws InterruptedException
    {
        double det=0;
        if(N == 1)
        {
            det = A[0][0];
        }
        else if (N == 2)
        {
            det = A[0][0]*A[1][1] - A[1][0]*A[0][1];
        }
        else
        {       //--------------------------------

                //-------------------------------
            det=0;
            for(int j1=0;j1<N;j1++)
            {    
                double[][] m = new double[N-1][];
                //-----------Здесь главный поток в обычном режиме
                for(int k=0;k<(N-1);k++)//-----Надо это организовать в потоке
                {
                    m[k] = new double[N-1];
                }

                
                //
                for(int i=1;i<N;i++)//-----Надо это организовать в потоке
                {
                    int j2=0;
                    for(int j=0;j<N;j++)
                    {
                        if(j == j1)
                            continue;
                        m[i-1][j2] = A[i][j];
                        j2++;
                    }
                }
                //-----------Здесь главный поток в обычном режиме
                det += Math.pow(-1.0,1.0+j1+1.0)* A[0][j1] * determinant(m,N-1);
            }
        }
        return det;
    }
}

I want to make the above loops in a thread using the Thread class, but alas. I'm trying to do it like this, creating a separate class:
/*
Класс для организации цикла в потоке
 */
package determinant;

/**
 *
 * @author WebSofter
 */
public class ThreadMethod1 implements Runnable//(содержащее метод run())
{ public int N;
  public double[][] m;
  
    void getM()
    {
        this.m = new double[this.N-1][];

        for(int k=0;k<(this.N-1);k++)
        {
            this.m[k] = new double[this.N-1];
        }
    }

    @Override
    public void run()		//Этот метод будет выполняться в побочном потоке
    {
        getM();
        //System.out.println("Привет из побочного потока!");
    }
}

And then use instead of the for loop like this:
package determinant;

import java.util.ArrayList;

class  CMatrix{
public double determinant(double A[][],int N) throws InterruptedException
    {
        double det=0;
        if(N == 1)
        {
            det = A[0][0];
        }
        else if (N == 2)
        {
            det = A[0][0]*A[1][1] - A[1][0]*A[0][1];
        }
        else
        {       //--------------------------------

                //-------------------------------
            det=0;
            for(int j1=0;j1<N;j1++)
            {    
                double[][] m = new double[N-1][];
                //-----------Здесь главный поток в обычном режиме
                /*
                for(int k=0;k<(N-1);k++)//-----Надо это организовать в потоке
                {
                    m[k] = new double[N-1];
                }

                */
                ThreadMethod1 tm1 = new ThreadMethod1();
                tm1.N = N;
                Thread thread1 = new Thread(tm1);
                thread1.start();
                m = tm1.m;
                //
                Thread.currentThread().sleep(2);//Задержка главного потока
                //
                for(int i=1;i<N;i++)//-----Надо это организовать в потоке
                {
                    int j2=0;
                    for(int j=0;j<N;j++)
                    {
                        if(j == j1)
                            continue;
                        m[i-1][j2] = A[i][j];
                        j2++;
                    }
                }
                //-----------Здесь главный поток в обычном режиме
                det += Math.pow(-1.0,1.0+j1+1.0)* A[0][j1] * determinant(m,N-1);
            }
        }
        return det;
    }
}

But an error comes out:
Exception in thread "main" java.lang.NullPointerException
  at determinant.CMatrix.determinant(CMatrix.java:48)
  at determinant.Determinant.main(Determinant.java:49)
Java Result: 1
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 1 секунда)

A small console program that calculates the determinant of a matrix from a file. Parses
the task well, but I need to use threads of the Thread class for this program, as shown above, but so far it's sad. What's my mistake?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
iliyaisd, 2014-12-07
@iliyaisd

Apparently, you are trying to get data from the thread before it has completed the calculation, and judging by the error - even before it had time to initialize the variable m. You want the thread to set some kind of flag (create a boolean variable in its class) that means the calculation is complete. Next, in the loop, you poll the threads for the end of the calculations. As I understand it, this is some kind of imitation of parallel programming? If so, then you need to poll all threads for these flags and merge the data when everyone is ready.

A
Artem, 2014-12-07
@mrRontgen

Try like this:

import java.util.concurrent.*;

class CMatrix {

    private double det = 0;

    int availableProcessors = Runtime.getRuntime().availableProcessors();
    ExecutorService executorService = Executors.newFixedThreadPool(availableProcessors);

    public void callback(Double[][] A, int N, Double[][] m, int j1) throws InterruptedException {
        det += Math.pow(-1.0, 1.0 + j1 + 1.0) * A[0][j1] * determinant(m, N - 1, false);
    }

    /**
     * 
     * @param A
     * @param N
     * @param isMain - if true then shutdown and await all threads
     * return
     * @throws InterruptedException
     */
    public double determinant(Double A[][], int N, boolean isMain) throws InterruptedException {
        //todo: if N=0
        if (N == 1) {
            det = A[0][0];
        } else if (N == 2) {
            det = A[0][0] * A[1][1] - A[1][0] * A[0][1];
        } else {
            for (int j1 = 0; j1 < N; j1++) {
                Calculate calculate = new Calculate(A, N, j1);
//                calculate.setcMatrix(this); //todo: you may call callback from other thread
                Future<Double[][]> result = executorService.submit(calculate);
                try {
                    callback(A, N, result.get(10, TimeUnit.SECONDS), j1);
                } catch (InterruptedException | ExecutionException | TimeoutException e) {
                    e.printStackTrace();
                }
            }
        }
        if (isMain) {
            executorService.shutdown(); //it just signal. System will wait for all task completed.
            executorService.awaitTermination(60, TimeUnit.MINUTES);
        }
        return det;
    }
}

class Calculate implements Callable<Double[][]> {

    private int N;

    private Double[][] A;

    private int j1;

    public Calculate(Double[][] a, int n, int j1) {
        N = n;
        A = a;
        this.j1 = j1;
    }

    private CMatrix cMatrix;

    public void setcMatrix(CMatrix cMatrix) {
        this.cMatrix = cMatrix;
    }

    public CMatrix getcMatrix() {
        return cMatrix;
    }

    @Override
    public Double[][] call() throws Exception {
        Double[][] m = new Double[N - 1][];
        for (int i = 1; i < N; i++) {//-----Надо это организовать в потоке
            int j2 = 0;
            for (int j = 0; j < N; j++) {
                if (j == j1)
                    continue;
                m[i - 1][j2] = A[i][j];
                j2++;
            }
        }
        return m;
    }
}

Multithreaded recursive functions are hardcore. I have no idea what will happen with the call stacks.
It may be better to first use multithreading to calculate the determinants of all additional minors and write them with parameters to some kind of LinkedList, and then, when all the tasks have completed, calculate the determinant in one cycle in the main thread.
PS See also forkjoin . There is RecursiveTask.
PSPS Here is recursive sorting docs.oracle.com/javase/8/docs/api/java/util/concur...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question