start() method called for a thread from a start() ... confusing - java

I've been fiddling with creating a thread on which the rendering runs, and I've come across this way of implementing it:
Class Main implements Runnable {
private Thread thread;
private boolean running = false;
public void start() {
running = true;
thread = new Thread(this, "renderingThread")
thread.start(); //calls run()
}
public void run() {
init(); //init glfw + create window
while(running) {
update();
render();
}
}
public static void main(String[] args) {
new Main().start()
}
Note that only the sections of the code that are related to threads have been included.
Now, the program flow looks something like this (correct me if I'm wrong): Construct new object of type/class Main (hence, reserve a place on the heap). Then, the start() method of object of type Main is called. running boolean is set to true. Then, a new thread is created via constructor Thread (Runnable target, String name) - in my case, the first parameter is this keyword, meaning that the reference of the object of type Main is passed as the first parameter (since the method has been called by the object of type Main). Then, the next line is what fiddles me the most. The thread reference calls the method start(), but it somehow refers to the run() method. How?
I'd be very thankful for a thorough explanation of how start() method for a thread object can refer to the run() method.

You create a new Thread with a Runnable target of this (the instance of Main class). Main implements Runnable means the method run() is overridden. The Thread class itself implements Runnable.
When you start the thread with the configuration above, the method start() causes the thread to begin execution; the Java Virtual Machine then calls the Thread object's run() method. It's said in the documentation. If you are curious, see the source code of the java.lang.Thread.
You can achieve the same effect with a simpler approach:
public class Main implements Runnable {
#Override
public void run() {
System.out.println("New thread");
}
public static void main(String[] args) {
new Thread(new Main()).start();
System.out.println("Main thread");
}
}

Take a look at the JavaDoc (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#start--)
When start() is called on the Thread Object it creates a new Thread and calls the run() method on that thread.

Related

What if you pass a no-arg in the Thread constructor and don't extend the Thread class?

What is happening in the background if I do this:
class TestThread {
public static void main(String[] args) {
Thread t = new Thread();
t.start();
System.out.println(t.getName());
}
}
I know that to create a new thread you must override the run() method by either extending the Thread class or by implementing the Runnable interface.
If we implement the Runnable interface we have to provide the target run method where the code which has to run concurrently is provided.
Also, If we do not override the run() method and do not extend the Thread or implement the Runnable, the main() thread will execute.
I would like to know as to what exactly will happen in the background when I execute the above code? Does the main have a run() method like other Threads? Will this create a new Thread in addition to the main thread?
/**
* If this thread was constructed using a separate
* Runnable run object, then that
* Runnable object's run method is called;
* otherwise, this method does nothing and returns.
*
* Subclasses of Thread should override this method.
*/
public void run() {
if (target != null) {
target.run();
}
}
Since you haven't set a Runnable target, nothing will happen.
Does the main have a run() method like other Threads?
Low-level API can be used for this purpose. They don't necessarily need to create a Thread instance to run a thread. Here is a good discussion: How main thread created by Java?
The new thread is created, starts, executes an empty* method, and terminates.
*) not really empty:
public void run() {
if (target != null) {
target.run();
}
}

Confusion regarding Runnable and Thread

I know this is a very tiny thing and would be quite easy for all you programmers out here, but I am stuck. I am not able to understand why this code snippet is printing out "Dog" instead of "Cat".
Runnable r = new Runnable() {
public void run() {
System.out.print("Cat");
}
};
Thread t = new Thread(r) {
public void run() {
System.out.print("Dog");
}
};
t.start();
Calling start() on a Thread object causes the JVM to spawn a new system thread which then proceeds to call the run method. Its default implementation looks something like this :
private Runnable target; // This is what you passed to the constructor
#Override
public void run() {
if (target != null) {
target.run();
}
}
Since you have overriden this very method in your anonymous Thread subclass declaration, this code never gets called, and the Runnable you injected is simply never used.
Also, whenever possible, leave the Thread class alone and put your code in Runnables instead.

How this below program is executing as thread reference is not passed

I am not able to understand the behavior of this below program ,well as i can see that there is no thread reference is there in which we can pass the myThread reference but still the program is executing please advise is it the main thread which is executing this program
class MyThread extends Thread
{
public static void main(String [] args)
{
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
System.out.print("two. ");
}
public void run()
{
System.out.print("Thread ");
}
}
the output is
one. two. Thread
This program consists of two threads.
The main() thread which is started when you start the program
The MyThread thread which you start from main()
This call:
t.start();
...will start a 2nd thread, which will run the code in the MyThread class's run method.
Because when you call t.start() , the run() method (you override) is executed,
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
The start() method :
- Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
I've always found the practice of letting your Main class extend something (in example code) dubious at best as it is unclear for beginners that when the main method is called there actually is no instance yet of the Main class (in this case the MyThread class).
So I've rewritten the example to make it more clear as to what happens:
public class Main
{
public static void main(String [] args)
{
// main gets called when starting your program (which is a thread created by the JVM for free)
MyThread t = new MyThread(); // You create a new Thread here
t.start(); // You start the thread
System.out.print("one. "); // In the mean time, the main thread keeps running here
System.out.print("two. ");
}
public static class MyThread extends Thread {
#Override
public void run()
{
System.out.print("Thread ");
}
}
}

Why does one thread stop the other thread from running?

I was going to use threads for each sound in a game engine I'm making. The problem is, whenever I make a new thread that has a while(true) statement, the other thread stops running.
I made a class to test this, and it only prints "goodbye", not "hello". I was wondering how to make the two threads run at the same time.
public class testor {
public static void main(String args[]){
testor test=new testor();
test.runTest();
}
class threadTest implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
threadTest test=new threadTest();
test.run();
while(true){
System.out.println("hello");
}
}
}
Since you are doing test.run(); you are only calling the method of that class but not starting the thread.
So in order to answer your question: there is no such a thread stopping the other thread from running? because you have only one Thread that is looping for ever and printing the message System.out.println("goodbye");
If that method is not looping for ever, it would return to the runTest method and then you would see the System.out.println("hello");
Summary:
For starting a Thread use the Thread::start method and not the run.
Using (new ThreadTest()).run() does not start a new Thread, but just invokes the run() method in the current thread.
To run the code in a separate thread do:
(new Thread(new ThreadTest())).start();
That's because you're not creating a new thread. Just naming a class something containing "thread" will not make it a thread, and a Runnable is no thread - it's a class like any other, with no special semantics or behaviour.
It's only special in that you can pass it to a Thread for execution.
public class Testor {
public static void main(String args[]){
Testor test=new Testor();
test.runTest();
}
class MyRunnable implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
Thread testThread = new Thread(new MyRunnable());
testThread.start();
while(true){
System.out.println("hello");
}
}
}
You should probably also adhere to the Java coding standards regarding your class and variable names if you do not want your code to look like an alien when combined with most other existing Java code.
Additionally, multithreading is more than just being able to start a new thread. You should also read about synchronisation issues - it's more complicated to do correctly than you might imagine.
Your run method contains an infinite loop.
The runTest() method creates the thread which means you'll have 2 execution stacks the main stack, and the runnable threadTest stack.
since you're running the thread method first that contains an infinite loop, you'll always get the output "good Bye".
Remove the infinite loop from run() method.

how to override thread.start() method in java?

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.

Categories