I have been trying to implement a parallel Depth First Search in Java for undirected graph. The approach I decided to implement uses one global stack which is shared by all the threads and n local stacks where n is the number of threads. Each thread stores the nodes of its sub-tree in its local stack. Initially the global stack contains the root of the tree and only one thread gets access to it while the other threads are waiting to be woken up by the working thread. The working thread retrieves and processes the root from the global stack, adds one successor to its local stack then pushes the rest of the successors, if they exist, to the global stack to be processed by other threads and wakes up all the waiting threads. All the other threads follow the same approach (i.e. when threads get a node from the global stack they push one successor to their local stack and the rest to the global stack then start accessing their local stack until it becomes empty).

The problem is it doesn't speed up. Will give me any suggestions on how to improve it? I'm new in parallel programming!

Thank you in advance!

Main method:

package dfsearch_v2;

import java.util.Calendar;
import java.util.Random;




public class DFSearch_v2 {


public static void main(String[] args) {
// TODO code application logic here
long ts_b, ts_e;
//number of nodes
int el_count=400;
int thread_count = 8;
int gCounter=0;
int vertices[][] = new int[el_count][el_count]; // graph matrix
boolean isVisited[] = new boolean[el_count];

for(int i=0;i<el_count;i++){
    for(int j=0;j<el_count;j++){
        Random boolNumber = new Random();
        boolean edge = boolNumber.nextBoolean(); 
        vertices[i][j]=edge ? 1 : 0;

    }   
}
DFSearch2 r[] = new DFSearch2[thread_count];
      ts_b = Calendar.getInstance().getTimeInMillis();
      for(int i = 0; i < thread_count; i++) {


        r[i] = new DFSearch2(el_count,vertices,isVisited,gCounter);
        r[i].start();

}      
    for(int i = 0; i < thread_count; i++) {

    try {

        r[i].join();

    } catch (InterruptedException e) {

    }

}
     ts_e = Calendar.getInstance().getTimeInMillis();
    System.out.println("Time "+(ts_e-ts_b));              
}    
}

Thread implementation:

package dfsearch_v2;

import java.util.Stack;



public class DFSearch2 extends Thread{

private boolean isVisit[];
private final Stack<Integer> globalStack;
int numberOfNodes;
//traversal is done ?
boolean isDone;
int adj[][];
// count visited nodes
int gCounter;

public DFSearch2(int number_Nodes,int adj[][],boolean isVisit[],int gCounter){
    this.numberOfNodes=number_Nodes;
    this.isVisit = isVisit;
    this.globalStack = new Stack<>();
    this.isDone=false;
    this.adj=adj;
    this.gCounter=gCounter;
    this.globalStack.push(number_Nodes-1);

}

public void run(){

    // local stack
    Stack<Integer> localStack = new Stack<>();
    while (!isDone) { 
        int k;
        synchronized(globalStack){
         k = globalStack.pop();  
         //pop until k is not visited
         while (isVisit[k]) { 
            if(globalStack.empty()) {
                isDone=true;
                return;
            }else{
                k=globalStack.pop();
            }
          }

        } 
        // traverse sub-graph with start node k
        DFSearchNode(localStack,k);
        yield();
        if(globalStack.empty()) {
           isDone = true; 
        }
        // if gCounter is not null unvisited node are pushed in globalStack
        if(isDone&&gCounter<numberOfNodes){ 
            isDone=false;
            //unvisited nodes are pushed in globalStack
            for (int i = 0; i < isVisit.length; i++) {
                if (!isVisit[i]) {
                  globalStack.push(i);  
                }  

            }
        }


 }


}    
    synchronized private void DFSearchNode(Stack<Integer>   localStack, int k){

        localStack.push(k);

        while (!localStack.empty()) {
           int s=localStack.pop();
           if (!isVisit[s]) {
                isVisit[s] = true;
                gCounter++;
                //System.out.println("Node "+s+" is visit");
               //first element is pushed into localStack and anothers in   globalStack
                 boolean flag = true; // local or global stack (true -> local; false ->global )
                 for(int i=numberOfNodes-1; i>=0; i--)
                 {
                   //   
                   if(i==s) continue;
                   //push another successors in global stack
                   if(adj[s][i]==1&&!flag&&!isVisit[s]){//visited nodes are not pushed in globalStack
                       globalStack.push(i);
                   }
                   //push first successor  in global stack
                   if(adj[s][i]==1&&flag&&!isVisit[s]) //visited nodes are not pushed in localStack
                   {
                       localStack.push(i);
                       flag=false; //only first element is pushed into localStack
                   } 

                 }                
           }


        }

}

}

One thing looks odd... "globalStack" is an instance variable, not static, so there is one "global" stack for each Thread. At the very least that's a terrible name

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.