Home > Mobile >  Java-How to search an array using a thread for each row and stop all running threads if found?
Java-How to search an array using a thread for each row and stop all running threads if found?

Time:12-02

I'm trying to search for the first occurrence of number 0 in an array by using a thread for each row and then interrupting all threads if 1 thread found the occurrence. I read multiple questions and answers but couldn't find a simple way and I tried using a variable "found" to not run the other threads. However, it's not working and I couldn't figure out the problem. I mainly wanted to use interrupt() instead of using a variable. Any help would be appreciated.

Search class

public class Search extends Thread {
    int low;
    int high;
    int[][] array; 
    static int id=0;  
    private static boolean found = false;
    private boolean done = false;

    public Search(int[][] array, int low, int high) {
        id  ;
        this.array = array;
        this.high = high;
        this.low= low;
    }

    public void run(){

        whileLoop:  while(!found && !done){
            for(int i = low; i < high; i  ){
                for(int j = 0; j < array[i].length; j  ){
                    if(array[i][j] == 0){
                        System.out.println("Found at: " i " " j   " By thread " id);
                        found = true;
                        done = true;
                        break whileLoop;
                    }
                }
            }
            done = true;
        }
       
    }
}

Main class

public class Main{
    public static void main(String[] args){
        int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
        SearchArray searchArray =  new SearchArray();

        searchArray.sArray(array);
    }
}


class SearchArray{

    public void sArray(int[][] array){
        int noThreads = array.length;
        Search[] threads = new Search[noThreads];

        for(int i = 0; i < threads.length; i  ){
            threads[i] = new Search(array, i*1 , (i   1) * 1);
            threads[i].start();
        }
    }
}

Output:

Found at: 0 1 By thread 5
Found at: 3 0 By thread 6
Found at: 1 2 By thread 5
Found at: 4 3 By thread 6

CodePudding user response:

Your found variable is not volatile, which means that after a certain thread finds it, and this thread set found to true, and other threads cannot immediately perceive it, and they will continue to find.

But even if you set it to volatile, it is not enough, because multiple threads may find it at the same time.

So, if you want to strictly control only one thread will print Found at:..., you need to use a lock instead of volatile(lock->check->act):

        public void run(){
            for(int j = 0; j < array[low].length; j  ){
                if (found) {
                    break;
                }
                if(array[low][j] == 0){
                    // lock,check,act
                    // if found, lock
                    // array here can be a lock, since all threads share this array
                    synchronized (array) {
                        // check
                        if (found) {
                            break;
                        }
                        found = true;
                        System.out.println("Found at: " low " " j   " By thread " id);
                        break;
                    }
                }
            }
        }

CodePudding user response:

First of all, using the volatile keyword is necessary since you are working with variables that are shared and used by different threads.

I recommend passing only the row to the thread and not the whole array. That would not be needed. And lastly, you could use a flag to check whether an occurrence of 0 was found or not. If it is found, stop the threads.

The below example fulfills your needs.

// the volatile keyword is important
public static volatile int[][] array = {{3,0,2,3,0,5},{2,4,0,2,6,5},{4,1,2,4,6,5},{0,2,1,4,0,5},{4,5,6,0,7,1},{9,7,4,1,1,3}}; //6 zeros
public static volatile boolean found = false;

public static void main(String[] args)
{
    for (int i = 0; i < array.length; i  ) // Iterate through each row
    {
        int finalI = i;

        Thread th = new Thread() // Create a new thread for each row
        {
            @Override
            public void run()
            {
                for (int j = 0; j < array[finalI].length; j  ) // Each thread will iterate through each element
                {
                    if(found) // If the element 0 was found, then break and stop the thread
                    {
                        System.out.println("Another thread found 0, so stopping this thread.");
                        break;
                    }

                    if(array[finalI][j] == 0) // If this is the thread that finds 0, then log and set flag to true
                    {
                        System.out.println(this.getName()   " found 0 at index "   finalI   ","   j);
                        found = true;
                        break;
                    }
                }
            }
        };

        th.start(); // Start each thread...
    }
}
  • Related