When you’re using multiple threads within a program, sometimes you just have to get rid of one of the threads. Maybe the thread is blocked on something. Maybe you don’t need it anymore and want to free up its resources. Maybe the application is trying to shut down cleanly. It doesn’t matter whether you’re programming in Java, C#, C++ or any other language — if you have threads, you need to terminate them at some point.
Most systems provide a way to “abort” or “kill” a thread, so it seems natural to use that feature to terminate a thread. Why else would it be there, after all, if you weren’t meant to invoke it?
In most cases, though, summarily terminating a thread is a bad idea. Depending on the platform, various problems may occur:
* The thread you’re terminating may be a system-managed thread that should never be terminated. (Think the event thread in most graphical user interface event-based systems.)
* Memory for the stack and other thread-specific resources may not be recovered by the system.
* The thread may not have a chance to clean up after itself and leave resources locked or otherwise unusable by others.
* The thread may be blocked on a low-level hardware condition and may be uninterruptible because of it.
Deadlock conditions — where one or more threads are waiting for resources (monitors or semaphores being the classic example) that are never released or unblocked — are classic side effects of unexpected thread termination. And they’re hard to recover from.
The best way to terminate a thread is to do it in cooperation with the thread. Instead of “killing” the thread, you ask it to commit “suicide” as soon as possible by returning from the method or function that the system invoked open starting the thread.
The easiest way to do this is to have a flag that each thread checks periodically to see if it should terminate itself. When the flag is set, the thread cleans up its resources as exits as quickly and gracefully as possible. A simple boolean variable is usually all that’s required. Expose a method or function that other threads can call to set the flag to true. When you want to terminate the thread, simply invoke the “quit” method and wait for the thread to terminate itself.
The only problem with this approach is that the thread in question may be blocked on something, such as waiting for data to arrive on the network. If there’s no explicit timeout specified in such cases, the thread may never unblock and may never notice that the termination flag has been set.
The solution is to have the “quit” method unblock the thread after setting the termination flag by closing or shutting down the underlying resource that the thread is blocked on. For example, if the thread is waiting for data to arrive on a socket, closing the socket from another thread will unblock the waiting thread, after which it can respond to the quit request and exit in a graceful manner.
Remember, never abort a thread — always ask it to quit. It’s the polite way to handle thread termination and it will save you a lot of grief in the long run.