This question already has answers here:
What's the difference between Thread start() and Runnable run()
(14 answers)
Closed 8 years ago.
I was learning the concept of Multithreading in Java where I came across this very interesting behavior. I was experimenting with various ways of creating a thread. The one under question now is when we are extending a Thread, not implementing the Runnable interface.
On a side note, I am aware that it makes perfect OO sense to implement the Runnable interface rather than to extend the Thread class, but for the purposes of this question, let's say we extended the Thread class.
Let t be my instance of my extended Thread class and I have a block of code to be executed in the background that is written within my run() method of my Thread class.
It perfectly ran in the background with the t.start(), but I got a bit curious and called t.run() method. The piece of code executed in the main thread!
What does t.start() do that t.run() doesn't?
That is what the class does. The t.start() will actually start a new thread and then calls run() in that thread. If you directly invoke run() you run it in your current thread.
public class Test implements Runnable() {
public void run() { System.out.println("test"); }
}
...
public static void main(String...args) {
// this runs in the current thread
new Test().run();
// this also runs in the current thread and is functionally the same as the above
new Thread(new Test()).run();
// this starts a new thread, then calls run() on your Test instance in that new thread
new Thread(new Test()).start();
}
This is intended behavior.
The t.start() simply does what it says: starts a new thread, that executes the run()'s portion of code. t.run() is a function call on an object, from the current working thread (in your case, main thread).
Just keep in mind: only when call start() function of a thread, a new thread is started, otherwise, calling it's functions (other than start()) is the same as calling a plain function on any other different object.
t.start() makes a native call to actually execute the run() method in a new thread. t.run() merely executes the run() in the current thread.
Now,
On a side note, I am aware that it makes perfect OO sense to implement the Runnable interface than to extend the Thread class
Actually, it makes perfect OO sense to follow either approaches (implementing Runnable or extending Thread). It is not that one is bad in OO sense. The advantage that you get by implementing Runnable is that you can make your class extend another class (which might actually break your OO design.)
Related
I couldn't find a question similar enough to this, but I do apologize if this is a duplicate.
//do something
//start
new Thread(r).start();
Runnable r = new Runnable() {
public void run() {
try{
Thread.sleep(5000);
//do something
}
catch(InterruptedException e){}
}
};//end new Runnable
My question is: Am I using a thread? or just a runnable object? Not sure if I am even asking a meaningful question?
I am new to threads, but my understanding of this code is : I am starting a new thread, passing it a runnable object, and it begins the overridden run method, in this case the thread will sleep for 5 seconds then do work.
Yes, you're using a Thread.
You create it by passing to its constructor a Runnable object.
"I am starting a new thread, passing it a runnable object, and it begins the overridden run method, in this case the thread will sleep for 5 seconds then do work."
This is correct, but the key point is missing: that this run method will be executed in another/new Thread, and not in the Thread from which you called start() on the Thread object which you created.
The Runnable interface just declares the fact that the class that implements it is able to be executed in a thread, so that it provides the interface to be called and executed by an external thread, nothing more.
A Thread implements Runnable since it's able to execute its own run() method but Runnable in general doesn't have anything related to threading itself. The default run() of Thread doesn't do anything, that's why you usually extend it and define the specific behavior of your thread.
But just to clarify, a ThreadPoolExecutor accepts Runnable objects exactly like a Thread. It's just the interface which declares that the class definition, is indeed, runnable (or executable).
You created a new anonymous implementation of Runnable interface.
This implementation povided the action to perform when executing the this implementation in a new Thread
You created a new Thread (new Thread(r)) and passed the anonymous instance to thread instance
When you started executing the thread (new Thread(r).start()), the jvm created a new thread. This new thread in turn invoked the run() method of the anonymous Runnable implementation.
An instance of Thread (as you create in the first line of code) represents a physical thread. When you call start(), the JVM will spawn a new thread (using the OS native methods to do so) and start its execution.
A Runnable is just an interface that defines the run() method (as you do in your second line of code). If you pass any object implementing Runnable to the Thread constructor, then the thread will run the code defined in the run() method.
Runnables are very lightweight since they only define one method, while Threads come with the heavy weight of a physical thread.
Directly creating a Thread is not recommended since it's an expensive operation. I highly recommend you look at the java Executors framework as it provides a flexible way of creating thread pools and submitting tasks (in the form of Runnables or Callables) to them. The Executors framework provides invaluable facilities for thread reuse.
I've been using threads for 2-3 days now, and I've got a quick question regarding methods. I'm making an Android application and it starts off with the main UI thread (let's call it the "UI Thread" for clarity). I'm spawning a new thread using the following code:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
someMethod();
}
});
thread.start();
My question is, will someMethod() also run on the new thread that I just created because I'm calling it from there? Or will it run on the UI thread? For reference, someMethod() is located outside outside of the method that's creating the new thread.
If someMethod() won't run on the new thread, how do I make it do so? Thanks.
will someMethod() also run on the new thread that I just created because I'm calling it from there?
Yes, that is exactly what happens. The method is just code. It's independent of the thread-of-control that happens to be running in it at a given point and time. This also means that there could be multiple threads executing that code at any given point in time if there are multiple cpu/cores.
You should take a look at Callable<V> and Future<T>, there you can call methods, that are not processed on the calling thread. You shouldn't work with threads anyway nowadays.
There are more modern approaches available.
Here is a link that should give you an idea http://www.vogella.com/articles/JavaConcurrency/article.html#futures
All of the actions taken by run, including calling someMethod, stay on the new Thread unless that code tells Java to run something in another thread (like with invokeLater or by using an Executor).
This is a Java syntax question, but just for some background.
Using android, I created a small app that went really slow and often crashed because when a button was clicked the onClick() method changed button images for various buttons. It was really clunky and slow and I found out after a search on the net that the problem is pretty common, and when changing lots of images in the onClick() method, its best to put them in a separate thread. And some kind person gave the code for doing this.
new Thread(new Runnable() {
public void run() {
quest.post(new Runnable() {
public void run() {
correct = nextQ();
}
});
}
}).start();
The nextQ() method and the "quest" TextView are mine. It's not really relevant to my question what they do, but nextQ does a database search and updates images, and running it outside the thread is really slow and crashy.
Now I copied and pasted this code into my code and it runs fine. A happy ending. But I dont feel comfortable using code I don't understand. And I don't know Java very well. SO I researched as best I could anonymous inner classes, but I'm still stumped by the code.
So the anonymous class extends thread, and as it's argument uses an anonymous class, implementing runnable, in which the "meat" of the code is placed..
Questions:
1)Why would I do this? I can understand using thread OR runnable, but why together?
2)How does this work? I went back to basics of thread and runnable, but I don't see how you use them together this way.
you are creating an anonymous implementation of the Runnable interface
you are passing that implementation to the constructor of the Thread class. So you are not extending Thread, you are just instantiating it, and pass an argument.
you then start() the thread. Thus the run() method of the passed argument will be invoked in a new thread.
You need to do this, because:
the Runnable defines what gets executed
the Thread actually executes it.
Your confusion is understandable, since a Thread is also Runnable. That's why in Java 5 the executors framework was introduces, which separated the execution mechanism (an executor) from the executed code (Runnable or Callable).
So the anonymous class extends thread,
No it does not. It implements Runnable.
1)Why would I do this? I can understand using thread OR runnable, but why together?
If you use Runnable, you still need to run it somehow, and one way to do that is to create a new Thread and give it to Runnable (which is what is being done here).
2)How does this work?
new Thread(runnable) creates a new Thread, which you can then start(). It will execute the code in the Runnable's run() method.
Runnable contains the code that should be executed (an alternative is Callable).
Thread controls how and when the code is executed (alternatives are ExecutorService or calling run() directly for synchronous execution on the current Thread)
In general (and to keep these two functions apart), you do not want to extend Thread, you only want to implement Runnable or Callable.
It is possible to extend Thread and directly implement run (rather than letting it delegate to the Runnable), but that is sort of old school. If they were to redesign the Java API today, Thread would probably not implement Runnable anymore. Thread is more of a Runner than it is a Runnable.
Please explain the output of the below code:
If I call th1.run(), the output is:
EXTENDS RUN>>
RUNNABLE RUN>>
If I call th1.start(), the output is:
RUNNABLE RUN>>
EXTENDS RUN>>
Why this inconsistency? Please explain.
class ThreadExample extends Thread{
public void run() {
System.out.println("EXTENDS RUN>>");
}
}
class ThreadExampleRunnable implements Runnable {
public void run() {
System.out.println("RUNNABLE RUN>>");
}
}
class ThreadExampleMain{
public static void main(String[] args) {
ThreadExample th1 = new ThreadExample();
//th1.start();
th1.run();
ThreadExampleRunnable th2 = new ThreadExampleRunnable();
th2.run();
}
}
The Thread.start() method starts a new thread, the entry point for this thread is the run() method. If you call run() directly it will execute in the same thread. Given that calling Thread.start() will start a new thread of execution, the run() method may be called after (as in you example) the rest of the main method executes.
Change your main method to call th1.start() and run repeatedly, you will see that sometimes it outputs:
EXTENDS RUN>>
RUNNABLE RUN >>
and sometimes it outputs:
RUNNABLE RUN >>
EXTENDS RUN>>
depending on how java chooses to schedule your 2 threads.
Check out the java tutorial on this.
When you call th1.run() you are running the run method in the current thread, so thus must happen before call to th2.run().
When you call th1.start() you the run method is being called on a new thread. In this case it is happening after the call to th2.run(). (In fact, it is theoretically possible that it could happen before the th2.run() ... but current and previous Sun implementations of thread.start() do not cause the current thread to immediately "yield" to the new thread.)
This illustrates a common mistake with using Java threads. If you want to run stuff on a new thread, you must call thread.start(). Directly calling thread.run() is almost always a mistake.
When you call .run(), the method is called and the code within executed the same as any other method. If you call .start() on a thread, though, the run() method will be run in that thread, and not sequentially in the main thread.
So when you call th1.start(), you have code executing in two threads at once: the main thread will go on to create th2 and then call its run method, while the th1 thread will call its own run method. There is no guarantee on the ordering of these, because they're executing in parallel.
executing run() is synchronous - executing start() is asynchronous.
The calls to run() are just a regular synchronous method call, and they happen in that order. Using th1.start(), a new thread is started - it's now a two horse rase - the two run methods are now executing independently - first one to the finish wins, and there is no guarantee about order.
But if the order is not guaranteed, why does the new Thread print later most of the time? In practice, it takes some time to start a new thread, so by the time it gets started, the other run() method has already ran. Even on a multi-core machine, where both threads can execute simultaneously, the new thread will typically come last, since the thread-startup involves more work.
Or is it?
I have a thread object from:
Thread myThread = new Thread(pObject);
Where pObject is an object of a class implementing the Runnable interface and then I have the start method called on the thread object like so:
myThread.start();
Now, my understanding is that when start() is called, the JVM implicitly (and immediately) calls the run() method which may be overridden (as it is in my case)
However, in my case, it appears that the start() method is not called immediately (as desired) but until the other statements/methods are completed from the calling block i.e. if I had a method after the start() call like so:
myThread.start();
doSomethingElse();
doSomthingElse() gets executed before the run() method is run at all.
Perhaps I am wrong with the initial premise that run() is always called right after the start() is called. Please help! The desired again is making executing run() right after start(). Thanks.
Um... the run() method will run in a different thread. That, per definition, means you cannot make any assumptions about before or after which statements in the current thread it will execute, unless you synchronize them explicitly.
Now, my understanding is that when start() is called, the JVM implicitly (and immediately) calls the run() method ...
That is incorrect. It does implicitly call run(), but the call does not necessarily happen immediately.
The reality is that the new thread becomes available to be scheduled at some point in time after the start() call is made. The actual scheduling is up to the native scheduler. It could happen immediately, or the parent thread could continue for a period before the child thread is scheduled.
To force your thread to start running immediately (or to be more accurate, to start running before doSomethingElse()), you need to do some explicit synchronization; e.g. something like this:
java.util.concurrent.CountDownLatch latch = new CountdownLatch(1);
new Thread(new MyRunnable(latch)).start();
latch.await(); // waits until released by the child thread.
doSomethingElse();
where
class MyRunnable implements Runnable {
private CountDownLatch latch;
MyRunnable (CountDownLatch latch) { this.latch = latch; }
public void run() {
doSomeStuff();
latch.countDown(); // releases the parent thread
doSomeMoreStuff();
}
...
}
There are other ways to implement the synchronization using the concurrency classes, or Java's mutex / wait / notify primitives1. But explicit synchronization between the two threads is the only way to guarantee the behavior that you require.
Note that the doSomething() call in the child thread will complete before the parent thread is released, but we can say nothing about the order of execution of doSomethingElese() and doSomeMoreStuff(). (One might run before the other and vice versa, or they might run in parallel.)
1 - Using wait / notify is not recommended, but it may be your only option if the concurrency APIs are not available; e.g. on Java ME.
run() is the first thing within your code that the new thread does, but there's some set-up work that the new thread does first, and there's no guarantee that any significant amount of work will by done by the new thread before the original thread goes on to call doSomethingElse().
You're right in thinking that there are no guarantees here. Making assumptions about the behaviour of multithreaded code is the source of much pain - try not to do it!
When you call myThread.start(), your thread becomes available for execution. Whether it will actually gain CPU, and for how long -- it's up the the OS scheduler. In fact, your run() may be getting control immediately, but losing it before it can do anything you can notice. The only way to ensure that your thread executes what you need before doSomethingElse() is to use explicit synchronization.
You've started a new thread. That thread runs in parallel to the thread that started it so the order could be:
pObject.run();
doSomethingElse();
or
doSomethingElse();
pObject.run();
or, more likely, there will be some crossover. pObject.run() may run in the middle of doSomethingElse() or vice versa or one will start before the other finishes and so on. It's important to understand this and understand what is meant by an atomic operation or you will find yourself with some really hard-to-find bugs.
It's even more complicated if two or more threads access the same variables. The value in one may never be updated in one thread under certain circumstances.
I highly suggest:
You don't make your program multi-threaded unless you absolutely need to; and
If you do, buy and read from cover to cover Brian Goetz's Java Concurrency in Practice.
calling the start method on a Thread Object may not make the jvm invoke the run() method immidiately, rather it makes the thread a runnable and ready for execution, in this case the parent thread first executes its code and then passes control to the child thread, if u want the child thread to execute before the parent thread code is executed use the chileThreadObject.join() method in the parent thread.