0

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!

Community
  • 1
  • 1
Derek Ziemba
  • 2,467
  • 22
  • 22

3 Answers3

4

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.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • This has cleared up a lot. I want to create a very lightweight background service that is always running even when the ui is not. I want the service to be the actual program with the widgets, notification, and UI never interacting with each other, only the background service. The app uses about 5-8MB ram when I feel there is no reason it should. Correct me if I'm wrong, but when the UI process is killed, and a widget is interacted with, does it launch the whole UI to respond to the widget? That's why I'm trying to do this Service, to make widgets more responsive after the ui is killed. – Derek Ziemba Jun 29 '14 at 02:09
1

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.

user253751
  • 57,427
  • 7
  • 48
  • 90
1

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.

awksp
  • 11,764
  • 4
  • 37
  • 44