10.1 User-Interface Thread and Other Threads

The user's impression of the performance of an application is greatly affected by its responsiveness. Putting the user interface into a separate thread from any other work makes the application feel far more responsive to the user and ensures that an unexpectedly long operation doesn't freeze the application's screen.

This user-interface thread is quite important in applets, where it is simple to use the screen-update thread to execute other tasks because you can easily call code from the paint( ) method. Although more effort is required to spawn a thread to execute other tasks, it is much better to do so, as otherwise you can easily block repainting the screen or other GUI responses. In Figure 10-1, the clock on the left has been resized to a quarter of its original size, but the paint( ) method has been unable to resize the clock drawing, as the paint( ) method is busy keeping the correct time. The clock on the right has been resized to a wide rectangular shape, and it keeps perfect time while also responding to the resize request because its paint( ) method always completes quickly.

Figure 10-1. The effect of timing on redrawing

If you are able to separate operations that slow processing (such as I/O) into specialized threads, your application will run more smoothly. It can carry on its main work while another thread anticipates the need for data, saves data to disk, etc. However, you should not pass work to another thread while your main thread just sits and waits until that other thread completes. In fact, doing this is likely to hurt performance rather than improve it. You should not use extra threads unless you have good design or performance reasons for doing so.

One useful technique is to use a separate thread to monitor the rest of the application and, when necessary, interrupt threads that are running beyond their expected execution time. This is more often a technique that ensures robustness, but it can apply to performance, too, when a calculation provides successively better approximations to the required result. It may be reasonable to interrupt the calculation after a certain length of time, assuming you have a good approximation calculated. This technique does not specifically require a supervising thread, as the timeout checking could be done within the calculation. It is often used in animation; the frame-display rate can be adjusted according to the time taken to display the frames, which in turn depends on picture resolution and the system environment.

All in all, using multiple threads needs careful consideration, and should be planned for in the design stage. Retrofitting an application to use threads at an intermediate or advanced stage can sometimes be done quite simply in some sections of the application, but is not usually possible throughout the application. In any case, care should be taken when changing the design to use more threads so that the problems illustrated in the next sections are avoided.