9

I have a multithreaded application. Several messages are coming to the application and are processed in separated threads. For this I am using classes ThreadPoolExecutor and FutureTask from package java.util.concurrent.

Occasionally I have some deadlocks in the application. When a deadlock occurs I want to interrupt the blocking thread and I want to log the stack trace of this thread so that I can later resolve the deadlock.

Is there any way how can we find the stack trace of a thread outside of that thread in Java?

Palo
  • 10,591
  • 7
  • 28
  • 34
  • You mean you want to detect deadlock and recover? Never done that, but using a stack trace for that doesn't sound like the right way to me.. – Enno Shioji Sep 17 '10 at 11:01
  • I need the stack trace so that I know where the thread stuck and can fix the problem so that the application works all right after restart. However I want to interrupt the blocking thread so that the application works until I find some time to fix the problem and release it. – Palo Sep 17 '10 at 11:10

6 Answers6

5

See here for how to generate stack traces, including how to do this programatically. From the console, Ctrl+Break will dump the stack traces to stdout. See also this SO question for more details.

Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • 5
    In UNIX environments, sending a “QUIT” (`kill -QUIT `) signal to the java process will also output the stack trace to the standard output. – Bombe Sep 17 '10 at 13:25
5

You could log the stack traces of all thread from time to time (or before killing the process) from within your application. To do that use:

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
for(Map.Entry<Thread,  StackTraceElement[]> e : m.entrySet()) {
    log(e.getKey().toString());
    for (StackTraceElement s : e.getValue()) {
        log("  " + s);
    }
}

When running nightly automated tests, sometimes some one of the test cases gets into a deadlock. I added a "TimeBomb" daemon thread that waits 30 minutes, and if then logs all stack traces as above.

Thomas Mueller
  • 48,905
  • 14
  • 116
  • 132
4

Before entering the deadlock region, set a field like,

thread = Thread.currentThread();

In your monitoring thread you can perform thread.getStackTrace(); to get the stack trace of that thread at any time.

om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

You use JStack. Here is a nice blog entry that details how to get stack traces.

Faisal Feroz
  • 12,458
  • 4
  • 40
  • 51
0

I wasn't sure if you wish to obtain the stacktrace from within the same JVM or externally, but if you wish to obtain the stack trace with external tools, the following will help:

  • The Java VisualVM tool can be used to connect to the running JVM, where the thread stack can be dumped. This is usually the preferred approach for most people using Java 6. Once VisualVM is launched, the thread dump of the process can be obtained by selecting the process in the Application tab. A Threads tab is now made available to view the threads in the running process, and in the same tab you'll find the "Thread Dump" button to extract the required information.
  • The jstack utility within the JDK can also be used to produce thread stacktraces.
Vineet Reynolds
  • 76,006
  • 17
  • 150
  • 174
0

When a deadlock occurs I want to interrupt the blocking thread ...

You could implement a periodic task to check for deadlocks (where deadlocks are java intrinsic or Lock based) and call interrupt on all threads involved in the scenario. However, this has no guarantees that it will solve your problem. Its likely the scenario that will just happen again. See Dr Heinz's article on a deadlock detector for details.

If fact, there is no guarantee that interrupt will even free up a blocked process like this. Its a far better approach to avoid the deadlock scenario in the first place by, for example, using locks with timeouts and retry strategies or 'try before you buy' approaches.

and I want to log the stack trace of this thread...

If you want to do this programatically, again, follow Dr Heinz's example. If not, just generate the thread dump when you've spotted the problem.

Is there any way how can we find the stack trace of a thread outside of that thread in Java?

Yes and no. You can dump the threads from other VMs but their stack traces may not be as useful as you might think to determining the causes of your deadlock. If a genuine deadlock has been detected (by the JVM itself on thread dump of your applications VM) you should have everything you need to debug the cause (more or less).

Toby
  • 9,523
  • 8
  • 36
  • 59