The platform doesn't provide any way for extensions to hook into the servlet unload event directly.
That being said, what you should do is have your cleanup code tied into the logic for stopThing() if defined in a thing template, or stopSubsystem() if defined in a subsystem (the cleanup methods work as well). When Thingworx is shut down it will attempt to stop all things and subsystems using those methods. This also supports the scenarios where the thing or subsystem are stopped individually by the user.
If your thing isn't enabled, then startThing() hasn't been called yet, so you probably haven't spun up your executor thread or thread pools yet. So either method should be safe in that respect.
In terms of which is more correct, it really depends on the architecture of your extension. If the threads are lightweight and can be spun up and down with little overhead (e.g., don't need to do any network handshakes), then having your logic in startThing and stopThing is fine. If there is a lot of overhead in the startup process, then you'll want to split things out a bit. You could create the executor thread and thread pool in initializeThing and have them begin processing in startThing, for example, then have the executor thread finish up processing and empty out the thread pool at stopThing and tear down the threads in cleanupThing.