Android Thread details - java

I can create a class which extends Thread and overrides the run method with a loop.
I then start it with myThread.start(), which create the OS thread and executes my run().
That's all good.
However, I don't quite understand the details. I'll have a go at working this out using test code when I get the chance, but before then can anyone answer these:
Q1. When does the constructor get executed, presumably when myThread is declared, or on start()?
Q2. What happens when my run() code completes? Is there a way of getting it to run again in the same thread (i.e. not losing all the thread variable values defined in class) Presumably calling start() might create a new os thread?
Q3. Presumably just calling myThread.run() would execute my run() in the context of the current activity, not mythread, in which case how could it access the thread variables?)
-Frink

A1) When you construct the instance of your MyThread class
A2) Threads cannot be run twice or restarted, as stated in the documentation.
A3) Yes, calling run() directly will execute that function in the current Thread, not in a new Thread. It doesn't make much sense to create a class that extends Thread if you want to just call run(). You should always call start().

Related

Run method V/S start method, confusion

I have some trouble understanding threads in Java so i searched up some answers on stack exchange and elsewhere. The summary of almost every answer was this:
The start method makes sure the code runs in a new thread context.
If you called run directly, then it would be like an ordinary method call and it would run in the context of the current thread instead of the new one.
The start method contains the special code to trigger the new thread; run obviously doesn't have that ability because you didn't include it when you wrote the run method.
What is meant by the second line?
When i create an object of the class that extends the thread class and then i invoke the run() method using that object, how can it possibly trigger the previous thread?
I am creating a new object, isn't it supposed to create a new thread automatically when i invoke the run() method directly?
From what i understand from that answer, if i have 2 classes A and B both inheriting the thread class. First i use the start method on the object of class A and then i directly invoke the run method on the object of class B, it would run in the context of the current thread, that is, the thread of class A?
.
Note:- This might look like a duplicate question but i can assure you that i've done ample studies regarding this topic but i haven't been able to get satisfactory answers!
I am creating a new object, isn't it supposed to create a new thread automatically when i invoke the run() method directly?
No. You are just creating a new Thread object that represents a thread. The thread haven't been started yet, and calling run will obviously not start it. If you call run, it will run on whatever thread that the calling code is running on.
From what i understand from that answer, if i have 2 classes A and B both inheriting the thread class. First i use the start method on the object of class A
Great, now we have started a thread using aObject.start(). However, the calling code is still running on the main thread. Only the stuff inside the run method of A is running on the new thread.
and then i directly invoke the run method on the object of class B, it would run in the context of the current thread, that is, the thread of class A?
As I said before, the current thread is still the main thread, not the thread represented by the object of A. Calling run on the object of B would simply run whatever is in it on the main thread.

Java - Run a method on Main thread, called from worker thread

How can I call and run a method on the main thread, called from its worker thread?
Main Thread code, (Foo() function is accessible from Main Thread):
Thread newThread = new Thread(myThread, myThread.getThreadName());
newThread.start();
Worker Thread code (newThread):
#Override
public void run(){
// need to call from here Foo() function - it has to run on the main thread
}
Thanks!
The words "call a method in another thread" have no meaning in Java.
You need to understand that Thread and thread are two different things: A thread is a path of execution through some code. A Thread is a Java object that can be used to start a new thread and manage its life cycle.
A new thread begins when some other thread calls t.start() where t refers to a Thread object. The thread begins executing the t.run() method, and it wanders into and out of function calls until it reaches the end of t.run(), at which point it dies. Meanwhile, other threads are following their own paths through the code.
At the lowest level, the only way for one thread to interact with another is by updating the fields of shared objects and classes.
Thread A can tell thread B to execute some function or another by sending a message (i.e., by updating a field in some object), but thread A can never make thread B do something. Thread B can only do what the code it is executing says to do. If the code says, look at field f, and if its value greater than zero, then call function foobar(), then that is what thread B will do. Or if the code tells it to pop a Runnable off of a queue and call the Runnable's run() method, then that is what the thread will do.
But no thread can change the code that some other thread is running once the thread starts running it. It can only change fields that influence what the code will do next.

Thread as constructor or run()

Is there any difference between creating a thread using the run() method as opposed to using the a constructor?
I noticed that I can start the thread and it acts the same in both ways.
new Thread MyThread().start
For example, as a constructor:
public class MyThread extends Thread{
public MyThread(){
// Do something
}
}
or as the run() method
public class MyThread extends Thread{
public void run(){
// Do something
}
}
Is there any difference between constructor or run()? Thanks!
It does not act the same in both cases
These cases are entirely different.
First, you probably need to learn about Threads and non-blocking processes. A Thread is used to do something asynchronously. So if you wanted to do some background task whilst doing something else then you would use a Thread. A good example is a GUI; you need one Thread to listen for GUI events (mouse clicks, button presses) and another to do any long running processing.
Now, onto your examples.
In Java a Thread consists of a run method that executes asynchronously when the start method is called. So when overriding Thread you change the run method. In reality you should never override Thread, you should use the constructor that takes a Runnable. There are many reasons for this, you should read up on concurrency.
Any code you place in your Thread constructor will be executed in the Thread that calls your constructor so this is not called asynchronously.
If you put the code in the run method, a new thread will be started upon invocation of start, which uses the run method as its starting point. If you put the code in the constructor, however, it will be run in the same thread as that which invoked the constructor, because a constructor is a special case of a method. Thus, if you want to start something in a new thread, put it in run, otherwise, put it in the constructor. Also, if you want to start a thread, never call Thread.run, because of the same reason not to put code in the constructor. Always call Thread.start().
The key difference is this:
The code in your constructor is executed immediately and synchronously when the constructor is invoked.
The program will stop and wait for that code to complete before moving on to the next line of code.
If you put the code inside run() method AND use Thread.start(), the code will be executed in a separate thread (i.e. it will run asynchronously).
Your program will continue to execute (moving to the next line of code immediately) while the code in your run() method runs in parallel.
This is helpful if the code in run() takes a very long time to execute.
That's because your program can continue to do other things while it waits for the thread to finish its work.
There is a difference. The constructor that creates the Runnable or subclass thereof runs in the main thread.
When starting a thread using:
new Thread(myRunnable).start();
you'll actually have run( of myRunnable run in the new thread.
NB You'll want to have a reference to the thread object in many cases. This code example is merely illustrative
On another note, never, ever, ever, give a thread this if starting within a constructor. Your computer could explode, or asphyxiation, drowning, or poisoning may occur.

Running a thread more than once

I have a Thread which runs my game loop. I want to be able to run this game loop each time I start a new game. But since the threads in Java can only be started once, how can I do this?
Create a new Thread around the same Runnable instance and start that.
Since you want the Thread that runs the game loop to keep running it, you need to code it something like this:
public class GameLoop implements Runnable {
...
public void run() {
while (gameNotFinished) {
// do stuff
}
}
}
If that is not working, then the chances are that the run() method is dying because of an exception that you are not catching / logging, and therefore not noticing.
1. When you say that "you need to run a thread", i means you want to start a sub-task on a separate thread.
2. Now if you mean this certain sub-task, then please prefer to run a new thread.
3. As you said But since the threads in Java can only be started once
This means that when a thread (thread of execution) completes its run() method, then the Thread object associated with it permanently looses its threadness, right....
But if this thread is from a pool, then the pool itself manages the Thread objects and its reused. Try using Executors from java.util.concurrent package.
1) The short answer is precisely what SLaks already said: just "...create a new thread around the same runnable instance and start that."
2) I think you might be confused about the distinction between the everyday meaning of "start", and the semantics of the Java Thread method "start()". This tutorial might help:
http://www.geom.uiuc.edu/~daeron/docs/javaguide/java/threads/states.html
3) Should you wish to re-use the same thread, you can use the methods "wait()" and "resume()":
http://www.javabeginner.com/learn-java/java-threads-tutorial

what does happen if I call run() method myself?

in the main method if I write this:
Thread aThread = new Thread();
aThread.run();
what will happen???
It will run in current thread. You will not start new thread this way.
But that doesn't really matter in your example since you gave new Thread no code to run anyway.
The thread that runs the main() code is the current thread. Creating a Thread object and calling one of its methods (other than start()) is like calling a method of class Integer or String - it doesn't create a new actual thread.
In your code example, execution of the main method will continue only when the run() method has finished running. This means that if the run() method has an endless loop (let's say it's waiting for incoming requests), then the main() method will never continue running, even if there are more lines of code after the call to run().
Calling aThread.start() creates a new actual thread (represented by the object aThread), makes the new thread call the run() method, and returns execution of the original thread to the next line in the main(). This means that the new thread can run around in circles forever, but it doesn't stop the main() code from creating more threads or performing other tasks.
It will just run like you're calling a normal method. So the method will be running in the same thread that calls the method.
It will run in the current Thread not in new Thread So If you call run method yourself it is meaningless. Because It doesn't create a new Thread.
If you call the start-method on a Thread class, the start-method will return after a while, but in concurrency will run the content of the run-method. If you call the run-method directly it will be executed and return to the caller, after the method is completely done - as every normal method call.

Categories