views:

67

answers:

2

I create a bunch of threads to do some processing:

new Thread("upd-" + id){
    @Override
    public void run(){
     try{
      doSomething();
     }
     catch (Throwable e){
      LOG.error("error", e);
     }
     finally{
      LOG.debug("thread death");
     }
    }
}.start();

I know i should be using a threadPool but i need to understand the following problem before i change it:

I'm using eclipse's debugger and looking at the threads in the debug pane which lists active threads.

Many of them complete as you would expect, and are removed from the debug pane, however some seem to stay in the list of active threads even though the log shows the "thread death" entry for these.

When i attempt to debug these threads, they either do not pause for debugging or show an error dialog: "A timeout occurred while retrieving stack frames for thread: upd-...".

there is some synchronization going on within the doSomething() call but i'm fairly sure it's ok and since the "thread death" log is being called i'm assuming these threads aren't deadlocked in that method.

i don't do any Thread.join()s, however i do call a third party API but doubt they do either.

Can anyone think of another reason these threads are lingering?

Thanks.

EDIT:

I created this test to check the Garbage Collection theory:

Thread thread = new Thread("!!!!!!!!!!!!!!!!")
{
    @Override
    public void run()
    {
     System.out.println("running");
     ThreadUs.sleepQuiet(5000);
     System.out.println("finished"); // <-- thread removed from list here
    }
};
thread.start();
ThreadUs.sleepQuiet(10000);
System.out.println(thread.isAlive()); // <-- thread already removed from list but hasn't been GC'd
ThreadUs.sleepQuiet(10000);

this proves that it is nothing to do with garbage collection as eclipse removes the thread from the thread list as soon as it completes and isn't waiting for the object to be de-referenced/GC'd.

+2  A: 

Could it be that the Thread objects themselves haven't been garbage collected yet, and that's all your seeing? Or perhaps Eclipse thinks you might want to see the thread (to examine its final state or whatever) and is keeping it around itself.

Do you have any evidence that this is a problem when you're not debugging?

Jon Skeet
when i first read your comment it sounded far fetched, but 5 seconds after "thread death" i run Thread.getAllStackTraces(), there is no thread with the same id. therefore it does sound like the thread isn't being GC'd ... now, why wouldn't they be getting GC'd??
pstanton
@pstanton: The garbage collector probably just hasn't run yet. It won't be run immediately after the thread dies automatically.
Jon Skeet
but other threads created and completing at roughly the same time have been removed! the lingering threads are not the most recent to complete and seem to stay there for quite some time
pstanton
@pstanton: Are you keeping a reference to them anywhere else? Perhaps the debugger is?
Jon Skeet
i'm 99% sure they aren't referenced anywhere. please see edit to question regarding GC
pstanton
how can i verify this isn't a problem when not debugging?
pstanton
A: 

i'm putting this down to eclipse debugger wierdness.

pstanton