There is no way to always execute something before your process exits. E.g. if you pull the plug out of the wall outlet, your computer shuts down immediately. Or if the process is killed by the operating system by removing it from the scheduler for CPU time, it also has no chance.
However, if you remove the code
try { mainThread.join(); }
catch (InterruptedException e) { }
Then it will at least be executed for certain cases, e.g. a normal termination of the process. Checking for the main thread here doesn't make sense, because either the shutdown hook is executed as a result of the main thread having finished its work (it exited the main() method), or the main thread will continue to run until the JVM decides to terminate (in case of termination from outside).
Compare the accepted answer of How to gracefully handle the SIGKILL signal in Java, which contains another example of what you're trying to do.