When using threads, it is important to know when a thread has finished processing. Waiting for a thread to perform an action or an event to happen is called thread synchronization.
It is typically sufficient to wait for a thread to end. When the thread ends, the application is alerted that the work the thread was assigned is complete or the thread failed. If a status is set by the thread and is supported by your specific API set, you can use the status to determine whether the thread successfully completed its work.
When a thread ends, the system reclaims its resources for reuse. You can also wait for a thread to end to reclaim more of the thread's resources for use by other threads.
Waiting for a group of threads to end can also be a good way for a larger application, such as a server, to give large amounts of application work to "worker" threads and have a single "boss" thread coordinate the work of the subordinate threads. Your API set can directly support this kind of waiting.