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.
Related
Suppose I have a class with 2 public static methods that control a single private instance of it's self. The basic structure of the class is below:
public class MyClass {
private static MyClass myclass = null;
private final Process, OutputStreamWriter, Strings, ints, etc....
private class constructor....
private class methods....
public static void command(String cmd) {
if(myclass == null) {
myclass = new MyClass();
}
myclass.setCmd(cmd);
}
public static void execute() {
myclass.run();
myclass.close();
}
}
I'm using this in an android application and I just want to verify how this works before I go to far into designing around this. Suppose that the command for the class comes from the UI thread. The UI thread calls the first static method
MyClass.command("parse and do what's in this string");
Now I expect the MyClass.execute() call, in some cases, may take almost up to a second to complete. I basically just want to verify that if I call the MyClass.execute() method from a Service or Runnable, that the execution will happen on that thread.
In the post static-method-behavior-in-multi-threaded-environment-in-java selig states that:
Memory in java is split up into two kinds - the heap and the stacks. The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can't access each others stacks. Each thread also has a pointer into the code which points to the bit of code they're currently running.
When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap. If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks....
Now since the UI thread made the call to the static method MyClass.command("Do this"), which technically instantiated the private local arguments and variables for that class, would this mean that the class is located on the UI thread's stack??? Meaning that if I called the MyClass.execute() from a service thread or runnable thread, the actual execution would happen on the UI thread while the service or runnable waits on it? Is my understanding of this correct?
Thank You!
Ok, there's a lot of misinformation in your post.
1)Services and Runnables do not, by default, have their own thread. Services run on the UI thread, although they can create a thread (an IntentService will do so by default). Runnables run on whatever thread calls run on them. But unless you post them to a Handler attached to another thread or to a Thread object, they won't start a new one.
2)All Java objects are on the heap, not the stack. The stack only holds primitive types and references to objects (but the objects themselves are on the heap).
3)Yes, each Thread has its own stack, so it can have its own set of local variables. But that doesn't prevent it from touching anything on the heap. That includes any object in the program
4)The only things that are private to a Thread are the local variables in the function. And notice that any local object is still on the heap and a reference to it can be saved and passed to another thread.
5)There is absolutely nothing that restricts threads to calling only static methods. You can call any type of method you want.
Classes are not located on stacks. There is no interaction between threads and classes.
If you call a method (including MyClass.execute()) the method will run on the same thread as its caller. So if you call it from a service, it will run in the service's thread (but note that this might also be the UI thread, unless you made the service run in a separate thread!). If you call it from some random thread, it will run on that thread.
The stack is not actually important to understanding what Java code does.
would this mean that the class is located on the UI thread's stack?
You're mixing up references and objects.
Objects are always on the heap in Java. Each thread has its own copy of the reference to the object in its own stack. So whatever changes command() makes will affect the object whose reference is on the stack -- the reference itself is unchanged, as well as all the other values on the stack, as the entity being altered is on the heap.
Meaning that if I called the MyClass.execute() from a service thread or runnable thread, the actual execution would happen on the UI thread while the service or runnable waits on it?
If you call MyClass.execute() from a different thread, the code for execute() will be executed on that different thread, period. Each thread keeps track of what code it is executing independently of other threads. So if you call MyClass.execute() from a different thread, the execution will not magically transfer to the UI thread, and would occur independently of other threads, with the exception of any shared objects.
It is me again, and I am pretty stuck with porting some code from c# to java.
As I now read, there are two main-ways in order to use multithreading in java.
There is the creation of a class, which inherits from thread, or the creation of a class, which implements Runnable.
(There is also the anonymous approach, I know ).
As I now painfully had to recognize, that porting the multithreading from c# to java could get me to refactor some of my code ( which I would like to avoid as much as possible) .
So, let me say, I have a class CLQueueWorker inheriting from Thread. My parent object (_oParentMAIN ) will keep a reference of this object.
It's "run" method SHOULD do some asynch actions ( which until now are all implemented in _oParentMAIN):
1) dequeue some data from an object, which was filled (and is maintained) in _oParentMAIN -->(my idea is now to create a static variable in CLQueueWorker, and work with this instead of
keeping it in the _oParentMAIN).
2) invokes a method-call on ui thread --> Do not know, how to refactor this, because until now
This method is a member of _oParentMAIN and I will not be able to invoke its call on
the ui thread, because CLQueueWorker does not know this member).
3) invokes another method on ui thread, which is responsible for ui-elements. --> here my problems also will be the same as in point 2.
So, I need some hints how to redesign this in the appropriate way.
Let me say, is it possible, that CLQueueWorker (which really spawns another thread) calls methods/throws events to/of _oParentMAIN AND PASSES EXECUTION BACK INTO MAIN thread ?
I hope, I could describe it clearly enough.
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.
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().
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.