Related
Say we have these two Runnables:
class R1 implements Runnable {
public void run() { … }
…
}
class R2 implements Runnable {
public void run() { … }
…
}
Then what's the difference between this:
public static void main() {
R1 r1 = new R1();
R2 r2 = new R2();
r1.run();
r2.run();
}
And this:
public static void main() {
R1 r1 = new R1();
R2 r2 = new R2();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
First example: No multiple threads. Both execute in single (existing) thread. No thread creation.
R1 r1 = new R1();
R2 r2 = new R2();
r1 and r2 are just two different objects of classes that implement the Runnable interface and thus implement the run() method. When you call r1.run() you are executing it in the current thread.
Second example: Two separate threads.
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1 and t2 are objects of the class Thread. When you call t1.start(), it starts a new thread and calls the run() method of r1 internally to execute it within that new thread.
If you just invoke run() directly, it's executed on the calling thread, just like any other method call. Thread.start() is required to actually create a new thread so that the runnable's run method is executed in parallel.
The difference is that Thread.start() starts a thread that calls the run() method, while Runnable.run() just calls the run() method on the current thread.
The difference is that when program calls start() method, a new thread is created and code inside run() is executed in the new thread: while if you call run() method directly, no new thread will be created and code inside run() will execute in the current thread directly.
Another difference between start() and run() in Java thread is that you cannot call start() twice. Once started, second start() call will throw IllegalStateException in Java while you can call run() method several times since it's just an ordinary method.
Actually Thread.start() creates a new thread and have its own execution scenario.
Thread.start() calls the run() method asynchronously,which changes the state of new Thread to Runnable.
But Thread.run() does not create any new thread. Instead it execute the run method in the current running thread synchronously.
If you are using Thread.run() then you are not using the features of multi threading at all.
invoke run() is executing on the calling thread, like any other method call. whereas Thread.start() creates a new thread.
invoking run() is a programmatic bug.
If you do run() in main method, the thread of main method will invoke the run method instead of the thread you require to run.
The start() method creates new thread and for which the run() method has to be done
t.start() is the method that the library provides for your code to call when you want a new thread.
r.run() is the method that you provide for the library to call in the new thread.
Most of these answers miss the big picture, which is that, as far as the Java language is concerned, there is no more difference between t.start() and r.run() than there is between any other two methods.
They're both just methods. They both run in the thread that called them. They both do whatever they were coded to do, and then they both return, still in the same thread, to their callers.
The biggest difference is that most of the code for t.start() is native code while, in most cases, the code for r.run() is going to be pure Java. But that's not much of a difference. Code is code. Native code is harder to find, and harder to understand when you find it, but it's still just code that tells the computer what to do.
So, what does t.start() do?
It creates a new native thread, it arranges for that thread to call t.run(), and then it tells the OS to let the new thread run. Then it returns.
And what does r.run() do?
The funny thing is, the person asking this question is the person who wrote it. r.run() does whatever you (i.e., the developer who wrote it) designed it to do.
Thread.start() code registers the Thread with scheduler and the scheduler calls the run() method. Also, Thread is class while Runnable is an interface.
The points, that the members made are all right so I just want to add something. The thing is that JAVA supports no Multi-inheritance. But What is if you want to derive a class B from another class A, but you can only derive from one Class. The problem now is how to "derive" from both classes: A and Thread. Therefore you can use the Runnable Interface.
public class ThreadTest{
public void method(){
Thread myThread = new Thread(new B());
myThread.start;
}
}
public class B extends A implements Runnable{...
If you directly call run() method, you are not using multi-threading feature since run() method is executed as part of caller thread.
If you call start() method on Thread, the Java Virtual Machine will call run() method and two threads will run concurrently - Current Thread (main() in your example) and Other Thread (Runnable r1 in your example).
Have a look at source code of start() method in Thread class
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* #exception IllegalThreadStateException if the thread was already
* started.
* #see #run()
* #see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
In above code, you can't see invocation to run() method.
private native void start0() is responsible for calling run() method. JVM executes this native method.
In the first case you are just invoking the run() method of the r1 and r2 objects.
In the second case you're actually creating 2 new Threads!
start() will call run() at some point!
The separate start() and run() methods in the Thread class provide two ways to create threaded programs. The start() method starts the execution of the new thread and calls the run() method. The start() method returns immediately and the new thread normally continues until the run() method returns.
The Thread class' run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread's run() method executes the run() method of the Runnable object in the new thread instead.
Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method, but in the latter case the code is actually executed in a new thread.
Start() method call run override method of Thread extended class and Runnable implements interface.
But by calling run() it search for run method but if class implementing Runnable interface then it call run() override method of Runnable.
ex.:
`
public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class
//implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it
//didn't show any error.
a.start();//this call run() of Thread
b.start();//this call run() of Thread
}
class A implements Runnable{
#Override
public void run() {
System.out.println("A ");
}
}
class B extends Thread {
#Override
public void run() {
System.out.println("B ");
}
}
`
Say we have these two Runnables:
class R1 implements Runnable {
public void run() { … }
…
}
class R2 implements Runnable {
public void run() { … }
…
}
Then what's the difference between this:
public static void main() {
R1 r1 = new R1();
R2 r2 = new R2();
r1.run();
r2.run();
}
And this:
public static void main() {
R1 r1 = new R1();
R2 r2 = new R2();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
First example: No multiple threads. Both execute in single (existing) thread. No thread creation.
R1 r1 = new R1();
R2 r2 = new R2();
r1 and r2 are just two different objects of classes that implement the Runnable interface and thus implement the run() method. When you call r1.run() you are executing it in the current thread.
Second example: Two separate threads.
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1 and t2 are objects of the class Thread. When you call t1.start(), it starts a new thread and calls the run() method of r1 internally to execute it within that new thread.
If you just invoke run() directly, it's executed on the calling thread, just like any other method call. Thread.start() is required to actually create a new thread so that the runnable's run method is executed in parallel.
The difference is that Thread.start() starts a thread that calls the run() method, while Runnable.run() just calls the run() method on the current thread.
The difference is that when program calls start() method, a new thread is created and code inside run() is executed in the new thread: while if you call run() method directly, no new thread will be created and code inside run() will execute in the current thread directly.
Another difference between start() and run() in Java thread is that you cannot call start() twice. Once started, second start() call will throw IllegalStateException in Java while you can call run() method several times since it's just an ordinary method.
Actually Thread.start() creates a new thread and have its own execution scenario.
Thread.start() calls the run() method asynchronously,which changes the state of new Thread to Runnable.
But Thread.run() does not create any new thread. Instead it execute the run method in the current running thread synchronously.
If you are using Thread.run() then you are not using the features of multi threading at all.
invoke run() is executing on the calling thread, like any other method call. whereas Thread.start() creates a new thread.
invoking run() is a programmatic bug.
If you do run() in main method, the thread of main method will invoke the run method instead of the thread you require to run.
The start() method creates new thread and for which the run() method has to be done
t.start() is the method that the library provides for your code to call when you want a new thread.
r.run() is the method that you provide for the library to call in the new thread.
Most of these answers miss the big picture, which is that, as far as the Java language is concerned, there is no more difference between t.start() and r.run() than there is between any other two methods.
They're both just methods. They both run in the thread that called them. They both do whatever they were coded to do, and then they both return, still in the same thread, to their callers.
The biggest difference is that most of the code for t.start() is native code while, in most cases, the code for r.run() is going to be pure Java. But that's not much of a difference. Code is code. Native code is harder to find, and harder to understand when you find it, but it's still just code that tells the computer what to do.
So, what does t.start() do?
It creates a new native thread, it arranges for that thread to call t.run(), and then it tells the OS to let the new thread run. Then it returns.
And what does r.run() do?
The funny thing is, the person asking this question is the person who wrote it. r.run() does whatever you (i.e., the developer who wrote it) designed it to do.
Thread.start() code registers the Thread with scheduler and the scheduler calls the run() method. Also, Thread is class while Runnable is an interface.
The points, that the members made are all right so I just want to add something. The thing is that JAVA supports no Multi-inheritance. But What is if you want to derive a class B from another class A, but you can only derive from one Class. The problem now is how to "derive" from both classes: A and Thread. Therefore you can use the Runnable Interface.
public class ThreadTest{
public void method(){
Thread myThread = new Thread(new B());
myThread.start;
}
}
public class B extends A implements Runnable{...
If you directly call run() method, you are not using multi-threading feature since run() method is executed as part of caller thread.
If you call start() method on Thread, the Java Virtual Machine will call run() method and two threads will run concurrently - Current Thread (main() in your example) and Other Thread (Runnable r1 in your example).
Have a look at source code of start() method in Thread class
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* #exception IllegalThreadStateException if the thread was already
* started.
* #see #run()
* #see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
In above code, you can't see invocation to run() method.
private native void start0() is responsible for calling run() method. JVM executes this native method.
In the first case you are just invoking the run() method of the r1 and r2 objects.
In the second case you're actually creating 2 new Threads!
start() will call run() at some point!
The separate start() and run() methods in the Thread class provide two ways to create threaded programs. The start() method starts the execution of the new thread and calls the run() method. The start() method returns immediately and the new thread normally continues until the run() method returns.
The Thread class' run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread's run() method executes the run() method of the Runnable object in the new thread instead.
Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method, but in the latter case the code is actually executed in a new thread.
Start() method call run override method of Thread extended class and Runnable implements interface.
But by calling run() it search for run method but if class implementing Runnable interface then it call run() override method of Runnable.
ex.:
`
public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class
//implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it
//didn't show any error.
a.start();//this call run() of Thread
b.start();//this call run() of Thread
}
class A implements Runnable{
#Override
public void run() {
System.out.println("A ");
}
}
class B extends Thread {
#Override
public void run() {
System.out.println("B ");
}
}
`
Here is the Example Code:
public class HelloRunnable implements Runnable {
#Override
public void run() {
System.out.println("Run Entered");
}
public static void main(String args[]) {
Thread obj=new Thread(new HelloRunnable());
obj.start();
System.out.println("ABC");
}
}
Output:
ABC
Run Entered
Why ABC before the run()'s code?
Even I create 3 threads. But still ABC print first;
obj.start();
obj1.start();
obj2.start();
Really I tried to search about this, but unable to find the query for this.
Simply because the HelloRunnable.run method is executed in another thread than the one printing ABC. They execute concurrently, that's the point of threads. Therefore, any of the two may access a certain resource, like the stdout, before the other.
When you call obj.start(), internally it spawns a new thread. So at that stage, you have 2 threads in your process, One is main thread, and one is new thread.
Each thread needs cpu to execute, and that's driven by cpu scheduling queue. If main thread hold the cpu, then out put will be what you saw. If context switch happens just after the statement obj.start();then cpu is given to new thread, Then you will see the thread output first and then the main output.
So the behavior is undeterministic as you can never predict that after which statement the context switch will happen.
Also what you see in the code is not what gets executed at the cpu. At the cpu assembly is executed. So even if you say that you were executing obj.start(), but you can never say on which assembly instruction you really were when context switch happened.
Would be reverse or like this. You started a "Thread". You are running on the main thread. So you have two independent running code. How do you guarantee that one will finish its work before the other ?
Try to sleep main thread after starting other threads. With
Thread.sleep(2000);
Then other threads would finish their works. You can see that ABC printed last.
public class HelloRunnable implements Runnable {
#Override
public void run() {
System.out.println("Run Entered");
}
public static void main(String args[]) {
Thread obj=new Thread(new HelloRunnable());
obj.start();
try{
Thread.sleep(2000);
}
catch(Exception e){}
System.out.println("ABC");
}
}
They are parallel works so you don't have a guarantee that ABC printed lastly or firstly. Depends on the machine CPU, works you have.
I'm confused about what is the current thread during the execution of a multithreaded program.
public class CurrentThread {
public static void main(String[] args) {
// FROM HERE: will always be "main-thread" the current thread ?
CurrentThread currentThread = new CurrentThread();
currentThread.testCurrentThread();
// TO HERE
}
private void testCurrentThread() {
// some other threads starts...
AThread athread = new AThread();
athread.start();
// some other threads starts...
}
class AThread extends Thread {
public AThread() {
setName("thread-a");
}
public void run() {
// FROM HERE: will always be thread-a the current thread during finish the run method ?
// some process
// TO HERE...
}
}
}
Suppose that launches multiple threads before and after start the thread AThread:
When you are inside the main method, whenever you call Thread.currentThread() will be "main-thread"?
When you are inside the run method of AThread, whenever you call Thread.currentThread() will be "a-thread"?
Thanks in advance.
currentThread: Returns a reference to the currently executing thread
object.
So when you are in your main method, that is your main thread and when you are in run method of AThread, then that is your a-thread.
If I understand your question correctly, you are unclear about the distinction of "main thread" and "current thread". First, the main thread is the thread that defines the context of your application; when the main thread ends, the application is (supposed to) end as well.
"Current thread" can be relative; you can have any number of threads running simultaneously--that's the point of threads--but "current thread" can mean "the thread of execution we're talking about now", or it can mean the Thread object which you get a reference to by calling the static method, as previously mentioned--that means "this thread, the path of execution I'm a step of". If you call the currentThread() method in your main class or the thread in which your main class is running, you'll get a reference to the main thread--the thread controlling the lifecycle of the application (this is drastically oversimplified). If you call currentThread() from any code that is running as a consequence of being part of or called by the run method of an object that extends thread, you get a reference to that instance of that object. This is essentially the long way of saying what Juned said above.
Additionally, I humbly submit that you may be mixing languages; CurrentThread is a class in C# but not in Java.
I am confused on the following:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable).
To start the thread's execution. we must call the Thread's method start(), which in turn calls method run() of the thread. And so the thread starts.
The method start() (unless I am wrong) must be called exactly and only once for each thread. As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage.
Now the javadoc
link text
says
Calls to execute will reuse previously constructed threads if available
I do not understand how this is implemented.
I provide in the execute method of the executor method my custom thread e.g.
ExecutorService myCachedPool = Executors.newCachedThreadPool();
myCachedPool.execute(new Runnable(){public void run(){
//do something time consuming
}});
How can this custom thread I delegeate to the executor framework be reused?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs?
Am I misunderstanding something?
Thank you.
Note that it's not Executor that calls start() - it's ExecutorService. And no, it's not calling start() twice. It doesn't start the task that you give it directly using Thread.start()... instead, it starts a thread which knows about that thread pool's queue of work. The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. So although the thread performs several tasks, Thread.start() is only called once.
EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks).
The same thread can execute multiple tasks. For a very simple example not using a thread pool, consider this:
public class MultiRunnable implements Runnable
{
private final List<Runnable> runnables;
public MultiRunnable(List<Runnable> runnables)
{
this.runnables = runnables;
}
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
(Ignore the potential thread safety issues of using a List<T> from multiple threads.)
You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. Does that help?
It is not calling start() more than once; instead the Thread in the pool never completes, but just stays alive---waiting. The source code is available for download if you want to look at it.
Each Thread in the thread pool can simply wait() for the Executor to hand it a new Runnable, but the Thread's own run() method has not completed. It simply waits for a new Runnable to be given to the Executor.
To "start" a thread more than once, create a runnable. For example:
//NO
private class T extends Thread { //not necessary to implement runnable
public void run(){
//...
}
}
void someMethod(){
T a = new T();
a.start();
a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}
Instead,
//Yes
private class T implements Runnable {
public void run(){
//...
}
}
void someMethod(){
T a = new T();
new Thread(a).start();
new Thread(a).start(); //YES YES YES
}
It is also possible to do this:
void someMethod(){
final Runnable r = new Runnable(){
public void run(){
//...
}
};
new Thread(r).start();
new Thread(r).start();
}
// r could also be a field of you class.