When a thread has completed its processing, it takes an action to end itself and release system resources for use by other threads.
Some API sets require the application to explicitly release resources associated with the thread when it ends. Other threads implementations (like Java™) garbage collect and clean up resources when it is appropriate to do so.
A thread can end in several ways. From a performance perspective, the best way to end a thread is to return from the initial routine that was called when the thread was started. Thread API sets typically provide mechanisms for ending the thread when returning from the initial routine is not an option.
Some API sets also support exception mechanisms. Exception mechanisms for ending a thread result in the thread ending when it takes an exception that is not handled. An example might be a Java exception that is thrown by a thread.
See your language-specific documentation for details on exceptions or other ways a thread can end itself.