Java "Thread-2" without stack prevents termination Java "Thread-2" without stack prevents termination multithreading multithreading

Java "Thread-2" without stack prevents termination


I don't understand why the breakpoint on Thread.start() did not work, but you could also try intercepting the thread >>creation<< by setting a breakpoint on the Thread constructors, or on the (internal) Thread.init() method.

The fact that the thread has the name Thread-2 implies that it was created by one of the constructors that generates a default thread name. That suggests that it was not created by the JVM or standard Java class libraries. It also narrows down the constructors that could have been used to create it.

How can I get more information about this thread ...

I can't think of any way apart from setting breakpoints.

... or allow it to terminate?

If you can find where it is created, you should be able to use setDaemon(true) to mark it as a daemon thread. However, this needs to be done before the thread is started.

Another possibility would be to find the thread by traversing the ThreadGroup tree and then calling Thread.interrupt() on it. ( Thread.getAllStackTraces() is another way of tracking down the thread object. ) However, there is no guarantee that the thread will "respect" the interrupt and shut down.

Finally, you could just call System.exit(...).


UPDATE

I mentioned that the thread might not respect interrupt() and I'm not surprised that stop() doesn't work. (It is deprecated, and may not even be implemented on some platforms.)

However, if you have managed to implement code that actually finds the mystery thread, you could dig around to find either the Thread subclass, or the Runnable that it is instantiated with. If you can print out the fully qualified class name, that will give you a big clue as to where it comes from. (Assuming that you are still having no success with breakpoints, then you may need to use "nasty" reflection to extract the runnable from the thread's private target field.)


Not sure if this enough for you, but the following code will allow you to try to interrupt any Thread by its name:

    //Set of current Threads    Set<Thread> setOfThread = Thread.getAllStackTraces().keySet();    //Iterate over set to find yours    for(Thread thread : setOfThread){        if (thread.getName().equals("Thread-2")) {            thread.interrupt();            break;        }    }

Also, take a look on this article from JavaSpecialists that tries to identify the creator of a Thread based on the fact that the constructor of Thread makes a call to the security manager. If we add a custom SecurityManager to our System, we may track the initiator of a Thread.


First off, you should change your _exit flag to volatile, since it's read from one thread (your main method), and written by another (JCF/Swing event handler), so it's possible your main thread isn't getting a "fresh" value. Specifically: the thread may be saving the field to a CPU register and not reloading it from memory as you're looping. 'volatile' will prevent that behavior:

private volatile boolean _exit;

However, based on your stack traces I don't think that's your problem, since we don't see your main method in there. But this should be done anyway, it's just good practice.

Assuming that doesn't fix it, I'm guessing your problem is that you have at least one other Window (besides AgentFrame) that isn't being disposed. The AWT thread won't stop until all Windows are disposed.

Put this at the end of your main method:

System.out.println(Arrays.toString(Window.getWindows()))

I'm guessing you're going to see more than just your DrawFrame there. If I were to guess, I'd say UISettingsFrame is in there, undisposed.