A popular way to simplify the design of complex systems is to use queues and asynchronous processing. Using such a design, you'd have queues set up to handle the different events that transpire in your system. Instead of methods being called directly, objects are created and placed in queues where they will be handled. At the other end of these queues are server programs with multiple threads that are set up to "listen" for messages coming in to these queues. The advantage of this type of simplified design is that it provides for reliable, robust, and extendable systems.
Better Utilization of CPU Time
Many times your application isn't really doing any work while it's still enjoying its timeslice. In my document retrieval example, one thread was waiting on the jukebox to load the platter. Obviously, this wait was a hardware issue and required no use of the CPU. Other examples of wait times include when you're printing a document or waiting on the hard disk or CD-ROM drive. In each case, the CPU is not being utilized. Such cases are candidates for being moved to background threads.
When Not to Use Threads
It's a common mistake for those new to threads to attempt to deploy them in every application. This can be much worse than not having them at all! As with any other tool in your programming arsenal, you should use threads only when it's appropriate to do so. You should avoid using multiple threads in your application in at least the following cases (described in the following sections): when costs outweigh benefits, when you haven't benchmarked both cases, and when you can't come up with a reason to use threads.