In java, does run() register a thread in a thread scheduler?
What about construct(),start() and register() ?
In java, does run() register a thread in a thread scheduler?
No. If you call the run() method directly, it is called as a normal method; i.e. it runs on the current thread, not a new one.
What about construct(),start() and register()
The start method creates a new thread, and in the process the thread will be registered with the scheduler. (However, the scheduler is a nebulous concept in Java. It is implied that one must exist, but its implementation and behavior are typically left to the host operating system. A pure Java program has almost no control over the way that the thread scheduler actually works.)
There are no construct() or register() methods in the Thread API. If you are referring to the Thread constructors, they only create a Thread object, and NOT the underlying thread that will do the work. The latter is only created when start() is called.
run() is the actual code in the thread; so you could do like:
Thread childThread = new Thread() {
public void run() {
// do stuff on a new thread
}
};
(Though I've been told extending Thread like that is ugly ;)
So calling run() itself won't create a new thread. To do that, you use start():
childThread.start();
So, I guess it does give the scheduler a new thread to deal with -- but that's way down on the OS level.
I'm not sure what you mean by construct() and register() though?
Related
Let's say I have a runnable class with two methods:
class ExampleClass implements Runnable {
public void shutdown()
{
currentThread().interrupt();
}
public void run(){
while(!currentThread().isInterrupted()){
System.out.println("thread is running...");
}
}
And I go and implement the class somewhere like so and pass it to a thread:
ExampleClass object = new ExampleClass();
Thread sideThread = new Thread( object, "Side Thread");
thread.start();
object.shutdown();
Will all this object and all its methods be running on sideThread or is just the run() method of object on the side thread?
i.e. When I call shutdown() will it actually interrupt the sideThread or will it just interrupt on the main thread where the object is instantiated?
There's no additional magic in Runnable. A Thread takes a Runnable and calls its run method on a new thread. End of story. Any other methods on that object are none of Thread's business. If you want to provide tighter integration between the calling thread and the created thread, that's on you to design.
What Silvio Mayolo says is correct, any thread can call any method of an object, passing a Runnable to a thread's constructor tells the thread to execute that Runnable's run method. If you want you can pass the same object implementing Runnable to several new threads and let them all run it. No magic here.
When you call Thread.currentThread(), that returns the thread that is executing the code. So as your posted code works now, if 1) a thread A starts a new thread B passing in this Runnable, and next 2) thread A calls shutdown on the Runnable, the result is that the interrupt flag is set on thread A, not on the thread B, the one executing the run method. Probably not what you want. It would be better to keep a reference to the new thread, and call interrupt on that.
Each thread gets a name generated for it. Try adding some lines like:
System.out.println("thread=" + Thread.currentThread().getName());
in your code and it will show you which thread is executing. You will see the new thread executing the run method, and the thread that created the new thread running the shutdown method.
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.)
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.
It may be a basic question, i was confused with this,
in one file i have like this :
public class MyThread extends Thread {
#Override
public void run() {
//stuffs
}
}
now in another file i have this :
public class Test {
public static void main(String[] args) {
Thread obj = new MyThread();
//now cases where i got confused
//case 1
obj.start(); //it makes the run() method run
//case 2
obj.run(); //it is also making run() method run
}
}
so in above what is the difference between two cases, is it case 1 is creating a new thread and case 2 is not creating a thread ? that's my guess...hope for better answer SO guys.Thanks
start() runs the code in run() in a new thread. Calling run() directly does not execute run() in a new thread, but rather the thread run() was called from.
If you call run() directly, you're not threading. Calling run() directly will block until whatever code in run() completes. start() creates a new thread, and since the code in run is running in that new thread, start() returns immediately. (Well, technically not immediately, but rather after it's done creating the new thread and kicking it off.)
Also, you should be implementing runnable, not extending thread.
Calling start() will create a new execution thread, and then the run() will be executed in the newly created thread
where as directly calling run() will execute the code in the current thread
the simple answer to your question is this:
run(): runs the code in the run() method, blocking until it's complete
start(): returns immediately (without blocking) and another thread runs the code in the run() method
Calling start starts the thread. It does the underlying work to create and launch the new thread, and then calls run on that new thread.
Calling run just calls the run method, on the current thread. You never call run directly, use start.
run() method after calling start() : this is executed by your thread which is created by you, it is allocated processor to run independently.
run() method called by you : executed from your calling thread.
In one line directly calling run() is synchronous (your code will block until run() returns) and calling start() (your code will not wait for run to complete as it is called in other thread obj) is asynchronous.
When you directly use start() method, then the thread will run once using the Runnable instance you provided to it and then the thread will be unusable.
But to leverage the Thread Pooling and Scheduling capabilities that are inbuilt in Java, extending a Runnable or Callable is the way to go.
start() starts the thread. run() just runs the code, in the current thread.
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.