I have a class "TestRunnable" which overrides run method by implementing Runnable.
Running overridden run method, as follow :
TestRunnable nr = new TestRunnable();
Thread t = new Thread(nr);
t.setName("Fred");
t.start();
What if i directly call t.run();
What happen if we don't call t.start(); ?
The run method is just another method. If you call it directly, then it will execute not in another thread, but in the current thread.
Here's my test TestRunnable:
class TestRunnable implements Runnable
{
public void run()
{
System.out.println("TestRunnable in " + Thread.currentThread().getName());
}
}
Output if only start is called:
TestRunnable in Fred
Output if only run is called:
TestRunnable in main
If start isn't called, then the Thread created will never run. The main thread will finish and the Thread will be garbage collected.
Output if neither is called: (nothing)
If you call start method then a separate thread will be allocated to execute the run method, means you achieve multi threading . But when you call run method directly then it becomes a normal method and main method itself will execute the run method , means no multi threading.
If run() method is called directly instead of start() method in Java code, run() method will be treated as a normal overridden method of the thread class (or runnable interface). This run method will be executed within the context of the current thread, not in a new thread.
Example
Let’s create a class and spawn two threads and cause some delay in the execution if they are real threads then there will be context switching – while one thread is not executing another thread will execute. When the start method is not called no new threads are created thus there won’t be any context switching and the execution will be sequential.
public class MyThreadClass extends Thread{
#Override
public void run(){
System.out.println("In run method " + Thread.currentThread().getName());
for(int i = 0; i < 5 ; i++){
System.out.println("i - " + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThreadClass mc1 = new MyThreadClass(“MyThread1”);
MyThreadClass mc2 = new MyThreadClass();
mc1.run();
mc2.run();
}
}
Related
This question already has answers here:
Please explain the output from Thread run() and start() methods
(4 answers)
Closed 8 years ago.
I was working on Threads when a question struck to my mind..If we can directly call run() method with the object of a class like any ordinary method then why do we need to call Thread.start() to call run() method..I tried both the methods as shown and got same result with both of them
First attempt by calling run() method directly
class Abc extends Thread
{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Abc");
}
try
{
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
class Xyz extends Thread
{
public void run()
{
try
{
for(int i=0;i<5;i++)
{
System.out.println("Xyz");
}
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
ob.run();
oc.run();
}
}
Second attempt by calling Thread.start()
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
Thread t1,t2;
t1=new Thread(ob);
t2=new Thread(oc);
t1.start();
t2.start();
}
}
If you call run() directly, the code gets executed in the calling thread. By calling start(), a new Thread is created and executed in parallel.
If you directly call run(), then all the work will be done on the main thread.
By using Thread.start, then it will executed on a new thread other than the main thread ;)
To observe what the difference is, increase your sleep calls to something longer like 10 seconds. This will make it obvious that you need Thread.start to avoid the first task waiting on the second.
In the case where you use Thread.start, you will see that output of both threads appears immediately.
In the case where you use run, you will see that the output of the first appears, then a 10 second delay, then the output of the second.
If you call run() method directly then code will run inline. To run the code in separate thread it is necessary to call Thread.start().
When you call start() method on thread reference it create span entirely context area. Then thread will have independent stack from where you are calling. More over start() invokes OS native thread to start it in separate memory context.
While run() method invocation considered as simple method call, and you won't have benefit of concurrency as its executing is current stack.
Can anyone explain to me why the first thread doesn't work and the second works perfectly:
public class Test {
public static void main(String args[]) throws InterruptedException {
TestThread1 t1 = new TestThread1();
TestThread2 t2 = new TestThread2();
t1.startThread();
t2.start();
Thread.sleep(4000);
t1.stopThread();
t2.stopThread();
}
}
class TestThread1 extends Thread {
private volatile TestThread1 thread;
public void startThread() {
thread = new TestThread1();
thread.start();
}
public void run() {
while (thread != null) {
System.out.println("RUNNING 1 ...");
}
}
public void stopThread() {
thread = null;
}
}
class TestThread2 extends Thread {
private volatile boolean finished = false;
public void run() {
while (!finished) {
System.out.println("RUNNING 2 ...");
}
}
public void stopThread() {
finished = true;
}
}
When I debug inside TestThread1 class: Inside startThread, the thread member is filled (so it is not null), inside run, thread member is null!!! And finally, inside stopThread, the thread member is not null!!!
Can anyone explain to me what is happening here?
Here, you have two instances of TestThread1 t1:
One is stored into your t1 local variable (in your main method).
One is stored into your thread instance variable (of t1).
t1 is never started, t1.thread is.
t1.stopThread() sets t1.thread to null, but it doesn't affect t1.thread.thread.
Since you're starting t1.thread, its run method is using t1.thread.thread:
This is never set to anything (so it's using null).
Calling t1.stopThread() like you do would only set t1.thread to null, which wouldn't affect t1.thread.thread.
More generally, you can't just "kill" a thread as such, but you can implement tests within the method to tell it to return under certain circumstances. What you've done with your second test is closer to this (using while (!finished) { ... } with a volatile variable).
I wouldn't limit the test to finished. It's also useful to test whether the thread was interrupted, in particular because if you run your runnables within an ExecutorService shutdownNow() will try to interrupt them (see this question).
I'd use while (!finished && !Thread.currentThread().isInterrupted()) { ... }.
(Note the difference between Thread.currentThread().isInterrupted() and Thread.interrupted(): they may seem similar, but the latter will also reset the status, which you might not want.)
Depending on what's within your loop (or whether there is a loop at all), you may want to use something like if (finished || Thread.currentThread().isInterrupted()) { return; } at various strategic points, where it makes sense.
There is two TestThread1 object being created, one is started and the other is stopped.
I suggest not extending Thread and instead wrapping your Runnable once.
TestThread1 t1 = new TestThread1();
t1.startThread();
This will simply call method startThread() on object t1. Inside this method you are creating a new Thread.
thread = new TestThread1();
thread.start();
But for this Thread thread instance variable is null(It is not null for t1).
So in both cases thread variable should be null.
Because in your main method you create a Thread1 Object. You then run startThread which creates a different Thread1 object inside the first one and sets it to the field thread. You then start the second object which didn't have its own thread field initialized. When run method is run on the second object the condition is false and the while loop doesn't start.
Your object hierarchy looks something like this
t1 (Thread1) {
thread(Thread1): {
thread: null;
run() {
while (thread != null) {...} // this is the method that is run - thread is null here since you never initialized it
}
};
startThread() {} // calls the run method on the nested thread object above
run() {
while (thread != null) {...} // this method is not run since t1.start() is never called in main()
}
}
in your case,
t2.start();
is calling run method directly, it is not creating thread inside startThread method.
so t1.stopThread() makes the volatile thread inside Thread1 class null. so you are getting like that.
solution
use
t1.startThread();
t2.startThread();
instead of
t1.startThread();
t2.start();
which makes 2 threads to create separate threads inside that method.
if you want a single thread of Thread1 then use runnable interface and create 2 threads and call startThread respectively rather than creating extra threads inside main.
I am a newbie to Java and wondering whether I can create threads in following way.
Desired Java Code :
Class MyClass {
Myclass(){
Statement1;//Create a thread1 to call a function
Statement2;//Create a thread2 to call a function
Statement3;//Create a thread3 to call a function
}
}
Is it possible to create threads like the above code?
The Java Concurrency tutorial includes a page on defining and starting threads. You might want to read through it along with the other pages in the concurrency tutorial.
Echoing GregInYEG, you should check out the tutorial, but the simple explanation is as follows:
You need to create an object class which either extends Thread or implements Runnable. In this class, create (actually, overload) a void method called "run." Inside this method is where you put the code that you would like this thread to execute once it is forked. It could simply be a call to another function if you wish. Then, when you would like to spawn a thread of this type, create one of these objects and call the "start" (not run!) method of this object. eg newThread.start();
It's important to call "start" and not "run" because a run call will simply call the method just like any other, without forking a new thread.
Still, be sure to read up in further detail and there are many more important aspects of concurrency, especially that of locking shared resources.
Yes, it is possible. You want to put your logic for each statement inside a Runnable implementation, and then pass each constructed Runnable to a new instance of Thread. Check out those 2 classes and it should become fairly obvious what you need to do.
I agree with all written here. The thread can be created in a two ways.
To extend thread class . YouTube Tutorial
To implement Runnable Interface YouTube Tutorial
Example for the first method
public class MyThread extends Thread {
public void run()
{
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Created Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
MyThread myThread = new MyThread();
myThread.start();
Second method to implement runnable interface
public class RunnableThread implements Runnable {
#Override
public void run() {
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Runnable Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
new Thread(new RunnableThread()).start();
So I think you can use both of these methods in you case statements
I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.
Suppose I have the following thread:
public class MyThread {
public void run() {
while (true) {
// do something forever
}
}
}
Then I instantiate the thread as follows:
MyThread thread = new MyThread();
What happens if I now call
thread.performSomeFunction()
Specifically, how does performSomeFunction interact with the infinite loop above? Does it have to wait for the loop to sleep? Or can they both run "concurrently"?
If your thread.performSomeFunction() is called from another thread, it does not have to contend with the infinite loop that is being run in the run() method. In this case, your MyThread instance is treated like another object that can have methods called on it.
Note that your infinite loop will not start until you start your thread instance.
You can test this out by putting the following line in both the run() method and your perfomrSomeFunction() method:
System.out.println("in [METHOD NAME]: " + Thread.currentThread().getName());
and replace the [METHOD NAME] with the actual method name.