In working through some stuff, I thought I’d drop these fun threading one-liners here…
Say you’ve got a main that just fires off some actions to start up a forever-running server, then dies. If you need a thread around to make sure your JVM doesn’t exit, one fun trick is to have a Thread call join() on itself (join waits for some usually other Thread to complete before returning).
I like to think of this as a 1 thread deadlock. A deadlock is just a cycle of resource requests holds – we’re used to seeing 2 thread deadlocks where thread A holds resource 1 and thread B holds resource 2 and they request each other’s resource. A thread joining itself is the same thing, but with just one resource – the thread completion itself.
In Clojure, you could create a function to do this like so:
(defn start-keepalive [] (.start (Thread. (fn [] (.join (Thread/currentThread))) "staying alive")))
If you then wanted to do a thread dump and verify a Thread named “staying alive” existed, there are a bunch of ways to do so:
- issue the standard interrupts of ctrl-break (windows) or ctrl-\ (*nix)
- find your pid with jps or other means, then use jstack to remotely dump the threads
- use jconsole or jvisualvm to connect to your vm and view the thread state
But you can also access the exact same info that those tools give you when you are in the JVM by calling the management mbeans directly. Sometimes this is useful if you’re in an IDE’s repl and the above methods either don’t work or are tedious. In that case, make a direct call:
(.dumpAllThreads (java.lang.management.ManagementFactory/getThreadMXBean) false false)
The last two flags dump owned monitors and synchronizer state, which can be useful for tracking down deadlocks and are usually both set to true in other thread dump mechanisms.
You can imagine some other fun tricks with ThreadMXBean if you check out the API: detect deadlocks, monitor thread counts, get a thread dump only for a particular thread, get cpu time for a particular thread, and a few other goodies.