2

I created my own thread class implementing the Runnable interface. But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself. Is this just an issue within Eclipse or would I also have problem running this on a Server? Do I have to change something calling the thread so that the main method can terminate properly?


Here's my basic self-made thread:

public class OwnThread implements Runnable {
   @Override
   public void run() {
      //do something
   }
} 

Here's the main class that won't terminate anymore:

public static void main(String[] args) {    
   Thread thread = new Thread(new OwnThread());
   thread.start();
}

When I debug it, the last called method is the exit()-method of the Thread-class. After going through these lines of code, the process goes on forever:

/**
 * This method is called by the system to give a Thread
 * a chance to clean up before it actually exits.
 */
private void exit() {
   if (group != null) {
      group.threadTerminated(this);
      group = null;
   }
   /* Aggressively null out all reference fields: see bug 4006245 */
   target = null;
   /* Speed the release of some of these resources */
   threadLocals = null;
   inheritableThreadLocals = null;
   inheritedAccessControlContext = null;
   blocker = null;
   uncaughtExceptionHandler = null;
}

Here's a screenshot of the thread that is running forever. The TestInterface class is where the main-method is located:

Thread running on forever

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
David Studer
  • 105
  • 9
  • Apart from "this is not the proper way to do it": Did you try adding a `thread.join()` at the end of `main`? – daniu Jun 27 '18 at 06:22
  • Usually a thread is considered 'terminated' when the `exit()` method is run. Have you debugged the state of the thread after that point? – L.Spillner Jun 27 '18 at 06:26
  • @daniu I tried it with `join()` as well as with `yield()`, did not change anything. But what would be the proper way to do it then? – David Studer Jun 27 '18 at 06:53
  • @L.Spillner the state of the started thread is **terminated**, but the main thread (where the mentioned `exit()`-method is called on) is still **running**. – David Studer Jun 27 '18 at 06:55
  • 1
    @DavidStuder In your example, no thread (neither the main thread nor the other started thread) is running. This program directly terminates. Maybe you simplfied your code too much. Look at my examples to get an idea. Otherwise please make a [mcve]. – Seelenvirtuose Jun 27 '18 at 07:00
  • @Seelenvirtuose The thing is, I ran it exactly like described with nothing going on in the `run()`-method and nothing else in the `main`-method and the issue still exists. I will edit my post and add a screenshot of the running thread, maybe it's better understandable afterwards. – David Studer Jun 27 '18 at 07:04
  • 1
    Ok. This is weird. Obviously both threads are terminated, but the application is still running. That might be an issue of Eclipse but it might also be an issue of the Java VM. Maybe a reinstall will help here. _This is not normal behavior and has nothing to do with your Java code._ – Seelenvirtuose Jun 27 '18 at 07:13
  • @Seelenvirtuose Thank you, I've already feared that it's not normal behaviour. I will **reinstall eclipse** and see what it brings. – David Studer Jun 27 '18 at 07:16

2 Answers2

3

But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself.

This is somewhat wrong. Your program does not terminate because there exists at least one non-daemon thread that still is running. The rule is: A Java program is terminated if all non-daemon threads are terminated.

I modified your program to make this behavior clear:

public class OwnThread implements Runnable {
    @Override
    public void run() {
        runForever();
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new OwnThread());
        thread.start();
        runForever();
    }

    private static void runForever() {
        while (true) {}
    }
}

Running that will create two threads that will run forever. One is the main thread which is started by running the program, and the other is the thread started inside the main method:

enter image description here

Modifying the above code by removing the call to runForever in the main method ...

public static void main(String[] args) {
    Thread thread = new Thread(new OwnThread());
    thread.start();
}

... will result in a different thread picture:

enter image description here

Here the main thread is gone because it is terminated. But the other started thread is still running.

Side note: Suddenly another thread appears - DestroyJavaVM. Have a look at the post DestroyJavaVM thread ALWAYS running for more information.

Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
  • But why is the other thread still running if it has been `exit`ed? – daniu Jun 27 '18 at 06:56
  • @daniu It is running because it is _not_ terminated (or exited as you say). – Seelenvirtuose Jun 27 '18 at 06:58
  • OP does state he found out that "the last called method is the exit()-method of the Thread-class" when debugging though. – daniu Jun 27 '18 at 07:03
  • 2
    @daniu Well ... This is because one thread is terminated: the main thread! I still speak about my example. I think, OPs problem is vice versa. The main thread is still running but the other thread terminated. That means that the main thread is still doing something. – Seelenvirtuose Jun 27 '18 at 07:05
  • @Seelenvirtuose Thank you very much for your explanation. It really helps to understand it a little bit better, but still I do not understand my case. – David Studer Jun 27 '18 at 07:09
  • @Seelenvirtuose I think you are right, the **main thread** is still running and doing something, but I don't know what or why. There is simply no other code than calling the self-made thread and as already mentioned, debugging the `main` method leads to this `exit()`-method, which really should **terminate** the main thread as I see it. – David Studer Jun 27 '18 at 07:12
  • @DavidStuder He's saying your `OwnThread#run` method doesn't finish IIUC. – daniu Jun 27 '18 at 07:14
  • @daniu Well did not understand it that way. But I am sure that the `OwnThread#run` is terminated properly and that the `main` thread causes the issue. – David Studer Jun 27 '18 at 07:19
  • 1
    @DavidStuder Hmmm. I would say that in your example both threads are properly terminated. In that case the application (the Java VM) should also terminate. – Seelenvirtuose Jun 27 '18 at 07:29
0

The issue is indeed not caused by the multithreading logic itself, it is caused by Eclipse and the respective JVM. Running the exact same code in Netbeans or on an Tomcat 8 Server did not lead to any problems. A reinstallation of Eclipse did not solve the malfunction within the Eclipse framework, but having the certainty that the issue does not cause any trouble on a server is sufficient for me to close the case.

Thanks to Seelenvirtuose for the hints and his effort.

David Studer
  • 105
  • 9