I've played around with JConsole because I may need this at work in order to monitor running Java processes. At home I finaly found a deadlock in my diploma thesis (distributed systems simulator). I should have used JConsole earlier. It helps so much to auto detect deadlocks in threads!
Just start your Java App like this:
java -Dcom.sun.management.jmxremote -jar VS-Sim.jar
Afterwards run the JConsole with "jconsole" in the CLI and select the JVM of the Java application you want to monitor.

In the "threads" tap you can watch all the threads including detect deadlocks. I found the following deadlock in VS-Sim, which seems to be a specific bug on multi core systems:
Name: Thread-2
State: BLOCKED on java.awt.Component$AWTTreeLock@1c98360 owned by:
AWT-EventQueue-0
Total blocked: 1 Total waited: 14,653
Stack trace:
java.awt.KeyboardFocusManager.clearMostRecentFocusOwner(KeyboardFocusManager.java:1777)
java.awt.Component.disable(Component.java:1286)
javax.swing.JComponent.disable(JComponent.java:3579)
java.awt.Component.enable(Component.java:1275)
java.awt.Component.setEnabled(Component.java:1238)
javax.swing.JComponent.setEnabled(JComponent.java:2647)
javax.swing.AbstractButton.setEnabled(AbstractButton.java:2064)
javax.swing.JMenuItem.setEnabled(JMenuItem.java:294)
simulator.VSSimulatorFrame.updateSimulatorMenu(Unknown Source)
- locked simulator.VSSimulatorFrame@a9ae05
simulator.VSSimulatorFrame.resetCurrentSimulator(Unknown Source)
simulator.VSSimulatorVisualization.finish(Unknown Source)
simulator.VSSimulatorVisualization.run(Unknown Source)
java.lang.Thread.run(Thread.java:619)
Name: AWT-EventQueue-0
State: BLOCKED on simulator.VSSimulatorFrame@a9ae05 owned by: Thread-2
Total blocked: 8 Total waited: 4,628
Stack trace:
java.awt.Frame.getExtendedState(Frame.java:744)
javax.swing.RepaintManager.addDirtyRegion0(RepaintManager.java:407)
javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:448)
javax.swing.JComponent.repaint(JComponent.java:4732)
java.awt.Component.repaint(Component.java:2970)
java.awt.Component.repaintParentIfNeeded(Component.java:2040)
java.awt.Component.reshape(Component.java:2028)
- locked java.awt.Component$AWTTreeLock@1c98360
javax.swing.JComponent.reshape(JComponent.java:4154)
javax.swing.JViewport.reshape(JViewport.java:854)
java.awt.Component.setBounds(Component.java:1972)
java.awt.Component.setBounds(Component.java:2109)
javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:869)
java.awt.Container.layout(Container.java:1432)
java.awt.Container.doLayout(Container.java:1421)
java.awt.Container.validateTree(Container.java:1519)
java.awt.Container.validate(Container.java:1491)
- locked java.awt.Component$AWTTreeLock@1c98360
javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:635)
javax.swing.SystemEventQueueUtilities
$ComponentWorkRequest.run(SystemEventQueueUtilities.java:127)
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
java.awt.EventDispatchThread.run(EventDispatchThread.java:121)