Reputation: 2197
I have a program where I want a specific class to run on a new Thread
every time an instance of it is created. To do this, I am using the extend Thread
inheritance method of multi-threading. However, what I would like to know is this: When I extend Thread
for a certain class, will every method of that class which I call (say in the constructor or later on) run on the Thread or will only the ones called in the run() method run on the new Thread?
Example:
public class Entity extends Thread {
Entity() {
super("Bob");
start();
method2(); //will this run on the new Thread alongside the one called in run()?
}
public void run() {
method1(); //will only this method run on the new Thread?
}
int method1() {
return 1;
}
int method2() {
return 2;
}
}
OR:
public class World {
public static void main(String args[]) {
Entity example = new Entity();
example.method2(); //will this run on the new Thread?
}
}
Upvotes: 1
Views: 2149
Reputation: 96385
Only the method1 call made from the Entity's run method gets called in the new thread created by calling run in Entity's constructor. The call to method2 on the entity from the main method is executed by the main thread. Likewise start is called by the main method, so the call to method2 from the Entity constructor is executed by the main thread.
In your Entity constructor, what happens is that the superclass' start method is called, resulting in a new Thread being created (where the entity object's run method will get called in the new thread), then the current thread proceeds to call method2. Not only does method2 not get called in the new thread, but, depending on how long it takes to get the new thread started, it's likely the run method on Entity could be executed after method2 is invoked (although which happens first is not specified, either thread could execute first).
You can test which thread is running something by logging the thread name. Using this.getName()
returns the name of the Thread object, not the name of the thread executing the code. You could change Entity's method1 and method2 code to
int method1() {
System.out.println("in method1 of " + this.getName()
+ ", executed from " + Thread.currentThread().getName());
return 1;
}
int method2() {
System.out.println("in method2 of " + this.getName()
+ ", executed from " + Thread.currentThread().getName());
return 2;
}
in order to see the difference between the two, which results in
in method2 of Bob, executed from main
in method1 of Bob, executed from Bob
in method2 of Bob, executed from main
Be aware that introducing printlns may change the order in which your program's threads execute.
A constructor is for initializing your object; having your thread start before your constructor finishes is error-prone, because the thread is executing the run method before the object has been completely initialized.
Having your Entity extend Thread is awkward for several reasons, you can't subclass from anything else and you risk accidentally overriding methods on Thread. Typically using executors that can use a threadpool is better than having objects try to manage their own dedicated threads. If you specifically want objects that run on their own threads and communicate asynchronously you might check out the Actor model and specifically Akka.
Upvotes: 0
Reputation: 3715
Only by calling the start()
method are you creating a new thread. Calling run()
or any other methods you defined in your class does not creates a new thread and still runs on the current thread.
Therefore the proper way to use the Thread
class is to only call the constructor and the start()
method outside of the class. Everything the class is supposed to do should fit in the run()
method.
Let's say you have the following code.
public class MyClass extends Thread {
public void myMethod() {
//implementation
}
public void run() {
myMethod();
//other implementation
}
}
public class Application {
public static void main(String args[]) {
new MyClass().start();
}
}
This code creates a new instance of MyClass
and calls its start()
method, which creates a new thread and automatically runs the run()
method on it.
In contrary, consider this code:
public class Application {
public static void main(String args[]) {
new MyClass().run();
}
}
or
public class Application {
public static void main(String args[]) {
new MyClass().myMethod();
}
}
Those code only executes the method on the current thread.
So to answer your question, the first method2()
call will not run on seperate thread. method1()
call will only run on the new thread if run()
is called through start()
method. The second method2()
call will not run on seperate thread.
Also, as mentioned in the other answer, it is never good practice to call start()
in the constructor.
Upvotes: 1