With multicore processors being widely used in the computing world, there is an increasing need to write multi-threaded software applications which fully utilize their computational power. A single-threaded program can run on only one core processor at a time. A single-threaded application running on a dual-core processor is losing 50% of the CPU resources. A program which executes multiple active threads concurrently makes the efficient use of multicore processors.
A thread is a single sequential path of execution which executes a set of instructions in a program. A program in execution is called a process. Each process runs in its own memory. A thread is also called a light-weight process since it runs in the memory allocated to the process. Thus a process can execute multiple threads with each thread having its own program counter and stack. Such a program is called a multi-threaded program.
Multiple threads running concurrently can also increase the throughput on a single processor. When the processor remains idle while a thread is waiting for a synchronous I/O operation to be performed, another thread can be taken for execution by the processor. Programs which need to perform asynchronous I/O operations with interleaved computation are candidates for implementing multithreading.
Monolithic single-threaded applications which perform independent tasks one after another can also be refactored to use multithreading, thus reducing their execution time. Programs which perform some degree of asynchronous tasks and take long time for computation can be made faster by using multi-threading. For e.g. if you have to read and parse messages from a message queue and it is taking long time to parse each message such that other messages keep waiting in the queue, then a thread can be created to parse each message after it is read from the queue. In this way multiple messages can be parsed concurrently.
In Java, multithreading can be implemented on console-based applications, programs which run as cron jobs on the server and GUI applications. A console-based application runs on the default “main” thread. Swing and AWT create an event-dispatching thread for event handling of its components. Lengthy computational tasks in Swing applications are generally executed by creating separate threads to avoid freezing of the screen.
Though, we do not create threads explicitly in the Java EE applications, the Servlet container executes each servlet request as a separate thread. Accurate implementation of synchronization is required when a data resource is being shared amongst multiple request threads.
Future of Multi-threading
Earlier computer performance was governed by Moore’s Law. As it gets harder to increase the processor clock rate, the computing world will be driven by Amdhal’s Law in future. Writing accurate multi-threaded programs and their performance tuning is important for efficient resource utilization and fair execution of all threads. Since threads may share a common data, implementing proper synchronization on atomic operations is crucial to avoid data contention, thread starvation and deadlock.