nafas
nafas

Reputation: 5433

Looping in Threads

Consider the following two designs of run method:

Approach A

public void run() {
    do {
        //do something
    } while (condition);
}

Approach B

public void run() {

    //do something...

    if (condition) {
       new Thread(this).start();
    }
}

The second approach seems cleaner to me, after some debate, I have been told it's not a good idea to use approach two.

Question:

  1. What are reasons (if there is any) that I shouldn't be using approach 2?

Upvotes: 0

Views: 386

Answers (5)

Meena Karthik
Meena Karthik

Reputation: 11

The 2nd option creates a new thread every time it is iterated, so it ends up being unnecessarily costly, especially when option A does the same thing but doesn't create new threads for every iteration.

Upvotes: 1

Raniz
Raniz

Reputation: 11123

They will behave very differently.

The first solution will loop until condition is false and then terminate.

The second solution will start a new thread and die until condition is false. It will likely accomplish what you want to do but it will waste a lot of resources allocating and destroying new threads.

Here's an example that loops over 5 values and prints the value and current thread name:

Loop:

Runnable loop = new Runnable() {

    int i = 0;

    @Override
    public void run() {
        do {
            System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
            i++;
        } while(i < 5);
    }
};
loop.run();

main: 0
main: 1
main: 2
main: 3
main: 4

Threaded:

Runnable thread = new Runnable() {

    int i = 0;

    @Override
    public void run() {
        System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
        i++;
        if(i < 5) {
            new Thread(this).start();
        }
    }
};
thread.run();

main: 0
Thread-0: 1
Thread-1: 2
Thread-2: 3
Thread-3: 4

As you can see, the threaded example prints each line on a different thread which is very wasteful and probably not what you want to accomplish.

Upvotes: 0

Thilo
Thilo

Reputation: 262852

The only good use-case I can find for Pattern B is if there is a significant delay before you want to re-run the method. For example for some kind of polling system that is supposed to run every X minutes until the system is being shut down.

In that case, using a scheduler instead of a Thread.sleep(fiveMinutes) makes sense to avoid tieing up resources unnecessarily (maybe you are holding on to a database connections or such).

Note that in that case, you'd be using a scheduler, not just Thread#start, so I am allowing for a rather liberal interpretation of Pattern B.

Upvotes: 0

Kayaman
Kayaman

Reputation: 73578

You have two things here. A loop, and a method that continuously runs itself again in a new thread until a condition is met (not a loop).

If you need a loop, you would choose the standard normal loop that everyone understands and works perfectly.

If you need to write a weird piece of code that creates new threads for no reason, and makes other developers doubt your skills and understanding, you would go for option B.

There's absolutely no sense in your choice B unless there would be something additional like a queue or ThreadPoolExecutor involved for re-invoking the method, so the method would add this at the end for invocation at a later time, sort of like a "lazy loop".

Upvotes: 4

Kieran
Kieran

Reputation: 344

Because approach B uses one more thread than approach A. Creating threads is expensive, for a number of reasons @see Why is creating a Thread said to be expensive?

Approach A is also a little clearer to the reader, IMO. The simplest option usually is.

Upvotes: 1

Related Questions