Arpssss
Arpssss

Reputation: 3858

Java MultiThread wait until child threads die

I have following Java code:

import java.io.*;
class Global{
public static int a = 0 ;
public static int b = 0 ;
}
public class Example{
public static void main(String args[]) {
    try {
        FileOutputStream fos = new FileOutputStream("1.dat");
        DataOutputStream dos = new DataOutputStream(fos);

        for (int i = 0; i < 20000; i++) {
            dos.writeInt(i);
        }
        dos.close();

        FileOutputStream fos1 = new FileOutputStream("2.dat");
        DataOutputStream dos1 = new DataOutputStream(fos1);

        for (int i = 20000; i < 40000; i++) {
            dos1.writeInt(i);
        }
        dos1.close();

        Exampless.createArray(20000); //static method call to set the static arr variable
        Exampless ex1 = new Exampless("1.dat"); //found number of matches in file
        Exampless ex2 = new Exampless("2.dat");
        Thread t1 = new Thread(ex1);
        Thread t2 = new Thread(ex2);
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("No. of Matches: " + (Global.a + Global.b ));

    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}
}

class Exampless implements Runnable {

public static int[] arr = new int[20000];
public String _name;

public Exampless(String name) {
    this._name = name;
}

static void createArray(int z) {
    for (int i = z; i < z + 20000; i++) {
        arr[i - z] = i;
    }
}

public void run() {
    try {
        int cnt = 0;
        FileInputStream fin = new FileInputStream(_name);
        DataInputStream din = new DataInputStream(fin);
        for (int i = 0; i < 20000; i++) {
            int c = din.readInt();
            if (c == arr[i]) {
                cnt++;
            }
        }
        System.out.println("File name: " + _name + " No. of Matches: " + cnt);
        if(_name == "1.dat")
            Global.a = cnt ;
        else if(_name == "2.dat")
            Global.b = cnt ;
    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}

}

There I am trying to run Exampless classes run method parallely. However, I want to make main thread wait until child thread finishes, which I have done using join. But, it makes execution of thread one after another. Can anybody help me how to solve this ? Another point is that, I want to share a variable (named as cnt which found number of matches in files)among two threads which I have done using Global class to found total number of matches. Is there any other nice solution ?

Upvotes: 1

Views: 1014

Answers (3)

assylias
assylias

Reputation: 328669

t1.join() waits until t1 is done, so you need to invert the 2 lines:

t1.start();
t2.start();
t1.join();
t2.join();

However, you would be better off using the high level concurrency package, and typically an ExecutorService:

ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(ex1);
executor.submit(ex2);
executor.shutdown();

Your next question:

I want to share a variable (named as cnt which found number of matches in files)among two threads which I have done using Global class to found total number of matches. Is there any other nice solution ?

What you are doing is not thread safe, unless those variables are volatile. If they are not, it is possible that your print in your main will not print the latest value of those variables.

A better solution would be to have Exampless implement Callable instead of Runnable, in which case you can return a value.

You can then retrieve the value from the future returned by the executor:

Future<Integer> future1 = executor.submit(ex1);
Future<Integer> future2 = executor.submit(ex2);

count1 = future1.get();
count2 = future2.get();

ps: you need to add error handling code around the future.get() calls

Upvotes: 4

MadProgrammer
MadProgrammer

Reputation: 347284

Rather then starting the next Thread after the previous one as finished, you of use a CountDownLatch to monitor the states of the Threads

Upvotes: 1

Jon Lin
Jon Lin

Reputation: 143906

Have you tried starting both threads first before joining?

    t1.start();
    t2.start();
    t1.join();
    t2.join();

Upvotes: 1

Related Questions