Home > Blockchain >  Java parallel array transforming using Thread and Phaser does not work correctly
Java parallel array transforming using Thread and Phaser does not work correctly

Time:11-18

It takes m iterations to transform the array according to the rule: a[i]=(a[i-1] a[i 1])/2 Also, according to the assignment, I must use Thread and Phaser. Using of Thread and Phaser is mandatory, and there is no way I can refuse to use them.

For transforming I use this code:

package lab3;
 
import java.util.concurrent.Phaser;
 
public class Program {
    public static void main(String[] args) 
    {
        int n = 100;
        int m = 100;
        int [] arr;
        arr = new int [n];
        int [] arr2;
        arr2 = new int [n];
        for (int i = 0; i<n; i  )
        {
            int r = (int)(Math.random()*50);
            arr [i] = r;
            arr2 [i] = r;
            System.out.print(arr[i] " ");
        }
        int [] arr3 = arr2.clone();
        System.out.println(" ");
        for (int p = 0; p<m; p  )
            for (int i = 1; i<n-1; i  )
            {
                arr [i] = (arr [i-1] arr [i 1])/2;
            }
        
        for (int i = 0; i<n; i  )
        {
            System.out.print(arr[i] " ");
        }
        System.out.println();
        Sum.arr = arr2;
        Sum.m=m;
        Phaser p = new Phaser();
            for (int i = 1; i<n-1; i  )
            {
                var x = new Sum (p, i);
                x.start();
            }
        for (int i = 0; i<n; i  )
        {
            System.out.print(Sum.arr[i] " ");
        }
        System.out.println();
        for (int i = 0; i<n; i  )
        {
            if (arr[i]!=Sum.arr[i])
                System.out.println("Error! Value is incorrect at position: " i ". Original val is: " arr[i] " Thead val is: " Sum.arr[i] " Before transform is: "  arr3[i]);
        }
    }
}
 
class Sum extends Thread 
{
    static int [] arr;
    static int m;
    Phaser ph;
    int i;
    
    public Sum(Phaser p, int i)
    {
        this.ph = p;
        this.i = i;
    }
    
    public static synchronized void trans (int i)
    {
        arr [i]= (arr [i-1] arr [i 1])/2;
    }
    
    @Override
    public void run ()
    {
        ph.register();
        for (int j = 0; j<m; j  )
        {
            trans(i);
            ph.arriveAndAwaitAdvance();
        }
        ph.arriveAndDeregister();
    }
}

However, the results of serial and parallel algorithms are not the same. Please tell me what am I doing wrong?

CodePudding user response:

I can see 2 problems:

  1. you don't wait for the Sum threads to finish before checking the results:
        Phaser p = new Phaser();
        for (int i = 1; i<n-1; i  )
        {
            var x = new Sum (p, i);
            x.start();
        }
        // YOU SHOULD WAIT HERE UNTIL ALL THE STARTED Sum THREADS ARE FINISHED
        for (int i = 0; i<n; i  )
        {
            System.out.print(Sum.arr[i] " ");
        }
        System.out.println();
    
  2. in Sum threads you don't wait for arr[i-1] and arr[i 1] to get computed before computing arr[i].
    Don't forget that Sum.run() are executed in parallel (because they are executed in different threads), and when some thread computes a[i], then there are no guarantees that the other threads have just computed the right iterations of a[i-1] and a[i 1].

CodePudding user response:

It seems like the question has transformed into:

how can I synchronize Sum.run()? how can I run it serially?

The answer is that you should probably use Phaser for synchronization because:

according to the assignment, I must use Thread and Phaser

You can learn how Phaser works here:

  1. official Phaser javadocs
  2. Guide to the Java Phaser on Baeldung

If the above resources aren't clear to you, then I can recommend Java Concurrency in Practice - this book explains concurrency in Java in great details and is ideal for novices in the topic.


Also I would recommend you to check one more time if you understood your assignment correctly.

Because right now (the way you explained it) your assignment looks weird:

  • one one hand the algorithm you described cannot be split into parallel subtasks: in order to compute a[i 1] we need a[i] from the same iteration.
  • on the other hand you should use threads, whose sole purpose is to perform work in parallel

To use threads with an algorithm that can only work sequentially is weird because this way you get only negatives: the program becomes more complicated and its performance decreases.

  • Related