Threads Concepts in Java

We are familiar with the benefits of multi-tasking. The concurrency results in faster throughput. Java supports multithreaded programming. In a multithreaded program, two or more parts of a program can execute concurrently. Each part of such a multithreaded program is known as a thread. Each thread has its own path of execution. Hence, multithreading is a specialized form of multi-tasking.

We are limiting our discussion to threads in this lecture.

Why Threads?

1. Maximum Utilization of resources

In a thread-based multitasking environment, the thread is the atom of code. It means that a single program can have two or more tasks concurrently.  Multitasking threads require less overhead compared to multitasking processes. Processes are heavyweight tasks that require their own separate address spaces using PCB. Multithreading features writing efficient programs to utilize processing power at its maximum level.

2. Minimum CPU Idle time

Faster throughput as mentioned earlier is possible because the idle time of CPU is minimum possible in the multi-threaded environment. In a single-threaded environment,  the program needs to wait for each of the tasks to complete before proceeding forward—despite most of the time the program is idle, waiting for input. In contrast, multithreading helps us reduce idle time as another thread is running regardless of other is in execution or waiting for the state.

States of a thread

The thread can be in any of the below-mentioned states:

State Description
New At the creation of a new thread
Ready Once it gets CPU time, the thread is ready
Running A ready thread turns to running
Suspended A running thread can get suspended
Resumed A suspended thread can be resumed
Terminated When a thread halts execution

Properties of a thread

Thread Priorities

Java assigns an integral number to each of the threads. The purpose is to determine the relative priority of the thread compared to all the threads available. It helps in the process called a context switch. In simpler words, it helps to decide the priority of allotting CPU to a specific thread. As a result, a lesser priority thread is switched by the higher-priority thread.  

Synchronization

Synchronization comes hand in hand with the multi-tasking environment. In order to solve the asynchronous behavior of the multi-threaded program, there has to be some ground to enforce synchronization.  For this purpose, Java implements a variant of interprocess synchronization: the monitor. The monitor is a control mechanism first defined by C.A.R. Hoare. A monitor can be considered as a single-seater ride. One and only one thread can ride at a time. Once a thread is inside a synchronized method, no other thread can be into it making it synchronization compliant code.

Messaging

Once a program is divided into one or more threads, it is obvious that there will be some information sharing between the threads. Java approaches messaging and information sharing with the help of JMS. Java’s messaging system allows a thread to enter a synchronized method of an object, and retain until it receives explicit notification from another thread to come out.

The Main Thread

When a Java program starts, one thread that begins running immediately is the main thread of your program. It is called so because it is the first one that is executed when the program begins. It is an inevitable thread for the following reason:

  • It is the thread from which other child threads get created.
  • It is the last thread to finish execution because it performs various cleanup and shutdown operations.

Hence, all the examples discussed until now have used a single thread of execution.

How to create Thread?

Java’s multithreading system is built on the pillars of the Thread class and Runnable interface. To create a new thread, you can either extend Thread or implement the Runnable interface. Thread class encapsulates a thread of execution.  It defines several methods that help manage threads. Referral to the ethereal state of a running thread cannot be done directly and is dealt with its proxy, the Thread instance that spawned it.

This was an overview of Java threads. We will discuss the life cycle of threads in the next lecture.