Reputation: 5433
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:
Upvotes: 0
Views: 386
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
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
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
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
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