Syrne
Syrne

Reputation: 117

Array of threads?

So I am having an issue understanding how to avoid sequential execution of threads. I am attempting to create an array of threads and execute the start() and join() functions in separate loops. Here's a code example of what I have now:

    private static int[] w;

static class wThreads implements Runnable {

        private final int i;

        public wThreads(int i) {
            this.i = i;
        }

        //Set member values to 1
        @Override
        public void run() {
            //doing specific stuff here
        }
    }

And here's where the threads are created in main:

int argSize = Integer.parseInt(args[0]);

    w = new int[argSize];

    //Initialize w
    for (int i = 0; i < argSize; i++) {
        wThreads wt = new wThreads(i);
        for (int j = 0; j < argSize - 1; j++) {
            Thread t = new Thread(wt);
            t.start();
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

So apparently this is not an example of threads working in parallel. They are waiting for each other to finish. I know that the join() and start() calls should be in different loops, but how can I reference the thread in a different loop than the one it's initially created in?

Do I need to create an array of threads in the class declaration? Should the loops be in there as well, and outside of main?

I'm quite confused and any info would be appreciated. Thank you!

Upvotes: 7

Views: 58812

Answers (3)

Dylan
Dylan

Reputation: 540

You can't do the join inside the loop where you are starting them (you can but as you have found, there is no parallelism). Create an array for the threads, start them in one loop and then create a second loop that does the join call. I don't think you want the inner for at all.

Thread myThreads[] = new Thread[argSize];
for (int j = 0; j < argSize; j++) {
    myThreads[j] = new Thread(new wThreads(j));
    myThreads[j].start();
}
for (int j = 0; j < argSize; j++) {
    myThreads[j].join(); //todo add catch exception
}

I suspect you want to do this yourself, but the standard way is using Executor, Thread Pools and such, see Oracle Tutorials

Upvotes: 17

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727097

Do I need to create an array of threads in the class declaration?

You need an array or some other collection. It is not necessary to put it at the class declaration level - it might very well be local:

w = new int[argSize];
//Initialize w
Thread[] t = new Thread[argSize];
// Create and start threads in the first loop
for (int i = 0; i < argSize; i++) {
    t[i] = new Thread(new wThreads(i));
    t[i].start();
}
// Let the threads run concurrently,
// and wait for them to finish in a second loop
for (int i = 0; i < argSize; i++) {
    try {
        t[i].join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Upvotes: 5

TheSuper
TheSuper

Reputation: 645

When you call join() on a thread, you are telling your program to wait until the thread is done executing, then to destroy the thread. Obviously, then, we want to spin up a bunch of new threads, let them run, and join them later. A thread is just a value like any other, and you can store it in a variable. So, in this case, let's make a new array of Threads:

Thread[] myThreads; // New array of threads
myThreads = new Thread[argSize]; // Same size as our int array

for (int i = 0; i < argSize; i++) {
    wThreads wt = new wThreads(i);
    // you don't need the second loop.
    myThreads[i] = new Thread(wt);
    t.start(); // Spins up a new thread and runs your code
}

Now, if you want to join the threads in another function, you must make your array of threads a member variable. Otherwise, you can make it as-is.

When you want to join your threads, just loop through the array and call join() on each member.

Thread current;
for (int i = 0; i < argSize; i++){
    current = myThreads[i];
    current.join();
}

This joins each thread in turn. The other threads will (possibly, depending on the scheduler) still run in parallel while this happens, if they are still running at the time.

Upvotes: 2

Related Questions